The main purpose of this commit is to add a stub for TRP event handling.
This currently amounts to listning to a TCP port and replying with a
brief message. Additionally, moved the active and new configurations
in the TR_INSTANCE struct into a container called TR_CFG_MGR. Other
instance types (TIDS, TRPS [new with this commit], and CFGWATCH)
instances now refer to the TR_CFG_MGR rather than to the TR_INSTANCE.
This resolves circular include dependencies and makes for a cycle-free
object hierarchy. Finally, introduced more complete use of talloc
for memory management, though this is probably not complete yet.
tr/tr.c \
tr/tr_event.c \
tr/tr_cfgwatch.c \
-tr/tr_tid.c
+tr/tr_tid.c \
+tr/tr_trp.c
tr_trust_router_LDADD = gsscon/libgsscon.la libtr_tid.la $(GLIB_LIBS)
include/tr_msg.h include/tr.h \
include/tr_idp.h include/tr_rp.h \
include/tr_comm.h include/tr_apc.h \
+ include/tr_tid.h include/tr_trp.h \
include/tr_filter.h \
include/tid_internal.h
*
*/
-#include <tr.h>
#include <tr_rp.h>
#include <trust_router/tr_name.h>
-#include <tr_config.h>
#include <tr_comm.h>
#include <tr_debug.h>
void tr_cfg_free (TR_CFG *cfg) {
talloc_free(cfg);
- return;
}
-TR_CFG_RC tr_apply_new_config (TR_CFG **active_cfg,
- TR_CFG **new_cfg)
+TR_CFG_MGR *tr_cfg_mgr_new(TALLOC_CTX *mem_ctx)
{
- if ((active_cfg==NULL) || (new_cfg==NULL))
+ return talloc_zero(mem_ctx, TR_CFG_MGR);
+}
+
+void tr_cfg_mgr_free (TR_CFG_MGR *cfg_mgr) {
+ talloc_free(cfg_mgr);
+}
+
+TR_CFG_RC tr_apply_new_config (TR_CFG_MGR *cfg_mgr)
+{
+ /* cfg_mgr->active is allowed to be null, but new cannot be */
+ if ((cfg_mgr==NULL) || (cfg_mgr->new==NULL))
return TR_CFG_BAD_PARAMS;
- if (*active_cfg != NULL)
- tr_cfg_free(*active_cfg);
+ if (cfg_mgr->active != NULL)
+ tr_cfg_free(cfg_mgr->active);
- *active_cfg = *new_cfg;
- *new_cfg=NULL; /* only keep a single handle on the new configuration */
+ cfg_mgr->active = cfg_mgr->new;
+ cfg_mgr->new=NULL; /* only keep a single handle on the new configuration */
- tr_log_threshold((*active_cfg)->internal->log_threshold);
- tr_console_threshold((*active_cfg)->internal->console_threshold);
+ tr_log_threshold(cfg_mgr->active->internal->log_threshold);
+ tr_console_threshold(cfg_mgr->active->internal->console_threshold);
return TR_CFG_SUCCESS;
}
static TR_CFG_RC tr_cfg_parse_internal (TR_CFG *trc, json_t *jcfg) {
json_t *jint = NULL;
json_t *jmtd = NULL;
- json_t *jtp = NULL;
+ json_t *jtidsp = NULL;
+ json_t *jtrpsp = NULL;
json_t *jhname = NULL;
json_t *jlog = NULL;
json_t *jconthres = NULL;
/* If not configured, use the default */
trc->internal->max_tree_depth = TR_DEFAULT_MAX_TREE_DEPTH;
}
- if (NULL != (jtp = json_object_get(jint, "tids_port"))) {
- if (json_is_number(jtp)) {
- trc->internal->tids_port = json_integer_value(jtp);
+ if (NULL != (jtidsp = json_object_get(jint, "tids_port"))) {
+ if (json_is_number(jtidsp)) {
+ trc->internal->tids_port = json_integer_value(jtidsp);
} else {
- tr_debug("tr_cfg_parse_internal: Parsing error, port is not a number.");
+ tr_debug("tr_cfg_parse_internal: Parsing error, tids_port is not a number.");
return TR_CFG_NOPARSE;
}
} else {
/* If not configured, use the default */
trc->internal->tids_port = TR_DEFAULT_TIDS_PORT;
}
+ if (NULL != (jtrpsp = json_object_get(jint, "trps_port"))) {
+ if (json_is_number(jtrpsp)) {
+ trc->internal->trps_port = json_integer_value(jtrpsp);
+ } else {
+ tr_debug("tr_cfg_parse_internal: Parsing error, trps_port is not a number.");
+ return TR_CFG_NOPARSE;
+ }
+ } else {
+ /* If not configured, use the default */
+ trc->internal->trps_port = TR_DEFAULT_TRPS_PORT;
+ }
if (NULL != (jhname = json_object_get(jint, "hostname"))) {
if (json_is_string(jhname)) {
trc->internal->hostname = json_string_value(jhname);
for (i = 0; i < json_array_size(jidps); i++) {
if (NULL == (temp_idp = (tr_cfg_find_idp(trc,
- tr_new_name((char *)json_string_value(json_array_get(jidps, i))),
- rc)))) {
+ tr_new_name((char *)json_string_value(json_array_get(jidps, i))),
+ rc)))) {
tr_debug("tr_cfg_parse_comm_idps: Unknown IDP %s.",
(char *)json_string_value(json_array_get(jidps, i)));
return NULL;
/* Join two paths and return a pointer to the result. This should be freed
* via talloc_free. Returns NULL on failure. */
-static char *join_paths(const char *p1, const char *p2) {
- return talloc_asprintf(NULL, "%s/%s", p1, p2); /* returns NULL on a failure */
+static char *join_paths(TALLOC_CTX *mem_ctx, const char *p1, const char *p2) {
+ return talloc_asprintf(mem_ctx, "%s/%s", p1, p2); /* returns NULL on a failure */
}
/* Reads configuration files in config_dir ("" or "./" will use the current directory). */
-TR_CFG_RC tr_parse_config (TR_CFG *new_cfg, const char *config_dir, int n, struct dirent **cfg_files) {
+TR_CFG_RC tr_parse_config (TR_CFG_MGR *cfg_mgr, const char *config_dir, int n, struct dirent **cfg_files)
+{
+ TALLOC_CTX *tmp_ctx=talloc_new(NULL);
json_t *jcfg;
json_error_t rc;
char *file_with_path;
int ii;
+ TR_CFG_RC cfg_rc=TR_CFG_ERROR;
- if ((!new_cfg) || (!cfg_files) || (n<=0))
- return TR_CFG_BAD_PARAMS;
+ if ((!cfg_mgr) || (!cfg_files) || (n<=0)) {
+ cfg_rc=TR_CFG_BAD_PARAMS;
+ goto cleanup;
+ }
+
+ if (cfg_mgr->new != NULL)
+ tr_cfg_free(cfg_mgr->new);
+ cfg_mgr->new=tr_cfg_new(tmp_ctx); /* belongs to the temporary context for now */
+ if (cfg_mgr->new == NULL) {
+ cfg_rc=TR_CFG_NOMEM;
+ goto cleanup;
+ }
/* Parse configuration information from each config file */
for (ii=0; ii<n; ii++) {
- file_with_path=join_paths(config_dir, cfg_files[ii]->d_name); /* must free result with talloc_free */
+ file_with_path=join_paths(tmp_ctx, config_dir, cfg_files[ii]->d_name); /* must free result with talloc_free */
if(file_with_path == NULL) {
tr_crit("tr_parse_config: error joining path.");
- return TR_CFG_NOMEM;
+ cfg_rc=TR_CFG_NOMEM;
+ goto cleanup;
}
tr_debug("tr_parse_config: Parsing %s.", cfg_files[ii]->d_name); /* print the filename without the path */
if (NULL == (jcfg = json_load_file(file_with_path,
JSON_DISABLE_EOF_CHECK, &rc))) {
tr_debug("tr_parse_config: Error parsing config file %s.",
cfg_files[ii]->d_name);
- talloc_free(file_with_path);
- return TR_CFG_NOPARSE;
+ cfg_rc=TR_CFG_NOPARSE;
+ goto cleanup;
}
- talloc_free(file_with_path); /* done with filename */
-
- if ((TR_CFG_SUCCESS != tr_cfg_parse_internal(new_cfg, jcfg)) ||
- (TR_CFG_SUCCESS != tr_cfg_parse_rp_clients(new_cfg, jcfg)) ||
- (TR_CFG_SUCCESS != tr_cfg_parse_idp_realms(new_cfg, jcfg)) ||
- (TR_CFG_SUCCESS != tr_cfg_parse_default_servers(new_cfg, jcfg)) ||
- (TR_CFG_SUCCESS != tr_cfg_parse_comms(new_cfg, jcfg))) {
- return TR_CFG_ERROR;
+
+ if ((TR_CFG_SUCCESS != tr_cfg_parse_internal(cfg_mgr->new, jcfg)) ||
+ (TR_CFG_SUCCESS != tr_cfg_parse_rp_clients(cfg_mgr->new, jcfg)) ||
+ (TR_CFG_SUCCESS != tr_cfg_parse_idp_realms(cfg_mgr->new, jcfg)) ||
+ (TR_CFG_SUCCESS != tr_cfg_parse_default_servers(cfg_mgr->new, jcfg)) ||
+ (TR_CFG_SUCCESS != tr_cfg_parse_comms(cfg_mgr->new, jcfg))) {
+ cfg_rc=TR_CFG_ERROR;
+ goto cleanup;
}
}
/* make sure we got a complete, consistent configuration */
- if (TR_CFG_SUCCESS != tr_cfg_validate(new_cfg)) {
+ if (TR_CFG_SUCCESS != tr_cfg_validate(cfg_mgr->new)) {
tr_err("tr_parse_config: Error: INVALID CONFIGURATION");
- return TR_CFG_ERROR;
+ cfg_rc=TR_CFG_ERROR;
+ goto cleanup;
}
- return TR_CFG_SUCCESS;
+ /* success! */
+ talloc_steal(cfg_mgr, cfg_mgr->new); /* hand this over to the cfg_mgr context */
+ cfg_rc=TR_CFG_SUCCESS;
+
+cleanup:
+ talloc_free(tmp_ctx);
+ return cfg_rc;
}
TR_IDP_REALM *tr_cfg_find_idp (TR_CFG *tr_cfg, TR_NAME *idp_id, TR_CFG_RC *rc)
* by scandir(). These can be freed with tr_free_config_file_list().
*/
int tr_find_config_files (const char *config_dir, struct dirent ***cfg_files) {
- int n = 0, ii = 0;
+ int n = 0;
n = scandir(config_dir, cfg_files, is_cfg_file, alphasort);
if (n < 0) {
perror("scandir");
tr_debug("tr_find_config: scandir error trying to scan %s.", config_dir);
- } else if (n == 0) {
- tr_debug("tr_find_config: No config files found.");
- } else {
- for (ii=0; ii<n; ii++) {
- tr_debug("tr_find_config: Config file found (%s).", (*cfg_files)[ii]->d_name);
- }
- }
+ }
return n;
}
#ifndef TID_INTERNAL_H
#define TID_INTERNAL_H
#include <glib.h>
-#include <trust_router/tid.h>
+#include <tr_rp.h>
+#include <trust_router/tid.h>
#include <jansson.h>
struct tid_srvr_blk {
tids_auth_func *auth_handler;
void *cookie;
uint16_t tids_port;
+ struct tr_rp_client *rp_gss; /* Client matching GSS name */
};
#ifndef TR_H
#define TR_H
+#include <talloc.h>
+
#include <tid_internal.h>
#include <trust_router/tr_name.h>
#include <tr_msg.h>
#include <tr_rp.h>
+#include <tr_trp.h>
+#include <tr_cfgwatch.h>
#include <tr_config.h>
typedef struct tr_instance {
- struct tr_cfg *new_cfg; /* unapplied configuration */
- struct tr_cfg *active_cfg;
+ TR_CFG_MGR *cfg_mgr;
TIDS_INSTANCE *tids;
- struct tr_rp_client *rp_gss; /* Client matching GSS name, TBD -- FIX ME */
+ TRPS_INSTANCE *trps;
+ TR_CFGWATCH *cfgwatch;
} TR_INSTANCE;
-TR_INSTANCE *tr_create(void);
+TR_INSTANCE *tr_create(TALLOC_CTX *mem_ctx);
void tr_destroy(TR_INSTANCE *tr);
#endif
#include <time.h>
#include <sys/time.h>
-#include <tr.h>
-
struct tr_fstat {
char *name;
int n_files; /* number of files in fstat_list */
int change_detected; /* have we detected a change? */
struct timeval last_change_detected; /* when did we last note a changed mtime? */
- TALLOC_CTX *ctx; /* what context should own configuration talloc blocks? */
- TR_INSTANCE *tr; /* what trust router are we updating? */
+ TR_CFG_MGR *cfg_mgr; /* what trust router config are we updating? */
};
typedef struct tr_cfgwatch_data TR_CFGWATCH;
#include <syslog.h>
#include <talloc.h>
-#include <tr.h>
+#include <tr_comm.h>
#include <tr_rp.h>
#include <tr_idp.h>
-#include <tr_comm.h>
#define TR_DEFAULT_MAX_TREE_DEPTH 12
#define TR_DEFAULT_TR_PORT 12308
#define TR_DEFAULT_TIDS_PORT 12309
+#define TR_DEFAULT_TRPS_PORT 12310
#define TR_DEFAULT_LOG_THRESHOLD LOG_INFO
#define TR_DEFAULT_CONSOLE_THRESHOLD LOG_NOTICE
TR_CFG_ERROR, /* General processing error */
TR_CFG_BAD_PARAMS, /* Bad parameters passed to tr_config function */
TR_CFG_NOPARSE, /* Parsing error */
- TR_CFG_NOMEM /* Memory allocation error */
+ TR_CFG_NOMEM, /* Memory allocation error */
} TR_CFG_RC;
typedef struct tr_cfg_internal {
unsigned int max_tree_depth;
unsigned int tids_port;
+ unsigned int trps_port;
const char *hostname;
int log_threshold;
int console_threshold;
/* TBD -- Trust Links */
} TR_CFG;
+typedef struct tr_cfg_mgr {
+ TR_CFG *active;
+ TR_CFG *new;
+} TR_CFG_MGR;
+
int tr_find_config_files (const char *config_dir, struct dirent ***cfg_files);
void tr_free_config_file_list(int n, struct dirent ***cfg_files);
-TR_CFG_RC tr_parse_config (TR_CFG *new_cfg, const char *config_dir, int n, struct dirent **cfg_files);
-TR_CFG_RC tr_apply_new_config (TR_CFG **active_cfg, TR_CFG **new_cfg);
+TR_CFG_RC tr_parse_config (TR_CFG_MGR *cfg_mgr, const char *config_dir, int n, struct dirent **cfg_files);
+TR_CFG_RC tr_apply_new_config (TR_CFG_MGR *cfg_mgr);
TR_CFG_RC tr_cfg_validate (TR_CFG *trc);
TR_CFG *tr_cfg_new(TALLOC_CTX *mem_ctx);
+TR_CFG_MGR *tr_cfg_mgr_new(TALLOC_CTX *mem_ctx);
void tr_cfg_free(TR_CFG *cfg);
+void tr_cfg_mgr_free(TR_CFG_MGR *cfg);
void tr_print_config(FILE *stream, TR_CFG *cfg);
-TR_IDP_REALM *tr_cfg_find_idp (TR_CFG *tr_cfg, TR_NAME *idp_id, TR_CFG_RC *rc);
-TR_RP_CLIENT *tr_cfg_find_rp (TR_CFG *tr_cfg, TR_NAME *rp_gss, TR_CFG_RC *rc);
+TR_IDP_REALM *tr_cfg_find_idp (TR_CFG *cfg, TR_NAME *idp_id, TR_CFG_RC *rc);
+TR_RP_CLIENT *tr_cfg_find_rp (TR_CFG *cfg, TR_NAME *rp_gss, TR_CFG_RC *rc);
#endif
#ifndef TR_TID_H
#define TR_TID_H
-#include <tr.h>
#include <tr_event.h>
+#include <tr_config.h>
-int tr_tids_event_init(struct event_base *base, TR_INSTANCE *tr, struct tr_socket_event *tids_ev);
+int tr_tids_event_init(struct event_base *base,
+ TIDS_INSTANCE *tids,
+ TR_CFG_MGR *cfg_mgr,
+ struct tr_socket_event *tids_ev);
#endif /* TR_TID_H */
--- /dev/null
+#ifndef TR_TRP_H
+#define TR_TRP_H
+
+#include <talloc.h>
+
+#include <tr_config.h>
+#include <tr_event.h>
+
+
+typedef struct trp_req {
+ int msg;
+} TRP_REQ;
+
+typedef struct trp_resp {
+ int msg;
+} TRP_RESP;
+
+typedef struct trps_instance TRPS_INSTANCE;
+
+typedef int (TRPS_REQ_FUNC)(TRPS_INSTANCE *, TRP_REQ *, TRP_RESP *, void *);
+typedef void (TRPS_RESP_FUNC)(TRPS_INSTANCE *, TRP_REQ *, TRP_RESP *, void *);
+typedef int (trps_auth_func)(gss_name_t client_name, TR_NAME *display_name, void *cookie);
+
+
+/* TRP Server Instance Data */
+struct trps_instance {
+ char *hostname;
+ unsigned int port;
+ TRPS_REQ_FUNC *req_handler;
+ trps_auth_func *auth_handler;
+ void *cookie;
+ struct tr_rp_client *rp_gss; /* Client matching GSS name, TBD -- FIX ME (??) */
+};
+
+
+/* prototypes */
+TRPS_INSTANCE *trps_create (TALLOC_CTX *mem_ctx);
+void trps_destroy (TRPS_INSTANCE *trps);
+int tr_trps_event_init(struct event_base *base, TRPS_INSTANCE *trps, TR_CFG_MGR *cfg_mgr,
+ struct tr_socket_event *trps_ev);
+int trps_accept(TRPS_INSTANCE *trps, int listen);
+
+#endif /* TR_TRP_H */
#ifndef TID_H
#define TID_H
+#include <talloc.h>
+
#include <arpa/inet.h>
#include <openssl/dh.h>
TR_EXPORT void tidc_destroy (TIDC_INSTANCE *tidc);
/* TID Server functions, in tid/tids.c */
-TR_EXPORT TIDS_INSTANCE *tids_create (void);
+TR_EXPORT TIDS_INSTANCE *tids_create (TALLOC_CTX *mem_ctx);
TR_EXPORT int tids_start (TIDS_INSTANCE *tids, TIDS_REQ_FUNC *req_handler,
tids_auth_func *auth_handler, const char *hostname,
unsigned int port, void *cookie);
-1, &authorization_insert, NULL);
/* Create a TID server instance */
- if (NULL == (tids = tids_create())) {
+ if (NULL == (tids = tids_create(NULL))) {
tr_crit("Unable to create TIDS instance, exiting.");
return 1;
}
}
/* returns 0 on authorization success, 1 on failure, or -1 in case of error */
-static int tids_auth_connection (struct tids_instance *inst,
- int conn, gss_ctx_id_t *gssctx)
+static int tids_auth_connection (TIDS_INSTANCE *inst,
+ int conn,
+ gss_ctx_id_t *gssctx)
{
int rc = 0;
int auth, autherr = 0;
nameLen = asprintf(&name, "trustidentity@%s", inst->hostname);
nameBuffer.length = nameLen;
nameBuffer.value = name;
-
+
if (rc = gsscon_passive_authenticate(conn, nameBuffer, gssctx, tids_auth_cb, inst)) {
tr_debug("tids_auth_connection: Error from gsscon_passive_authenticate(), rc = %d.", rc);
return -1;
}
}
-TIDS_INSTANCE *tids_create (void)
+TIDS_INSTANCE *tids_create (TALLOC_CTX *mem_ctx)
{
- TIDS_INSTANCE *tids = NULL;
- if (tids = malloc(sizeof(TIDS_INSTANCE)))
- memset(tids, 0, sizeof(TIDS_INSTANCE));
- return tids;
+ return talloc_zero(mem_ctx, TIDS_INSTANCE);
}
/* Get a listener for tids requests, returns its socket fd. Accept
#include <stdlib.h>
#include <string.h>
+#include <talloc.h>
#include <tr.h>
+#include <tr_config.h>
-TR_INSTANCE *tr_create() {
- TR_INSTANCE *tr = NULL;
- if (tr = malloc(sizeof(TR_INSTANCE)))
- memset(tr, 0, sizeof(TR_INSTANCE));
+TR_INSTANCE *tr_create(TALLOC_CTX *mem_ctx) {
+ TALLOC_CTX *tmp_ctx=talloc_new(NULL);
+ TR_INSTANCE *tr=talloc_zero(tmp_ctx, TR_INSTANCE);
+ if (tr != NULL) {
+ tr->cfg_mgr=tr_cfg_mgr_new(tr);
+ if (tr->cfg_mgr != NULL) {
+ /* success, hand over ownership */
+ talloc_steal(mem_ctx, tr);
+ }
+ }
+ talloc_free(tmp_ctx);
return tr;
}
void tr_destroy(TR_INSTANCE *tr) {
- free (tr);
+ talloc_free (tr);
}
TALLOC_CTX *tmp_ctx=talloc_new(NULL);
TR_CFGWATCH *new_cfg;
- new_cfg=talloc(tmp_ctx, TR_CFGWATCH);
+ new_cfg=talloc_zero(tmp_ctx, TR_CFGWATCH);
if (new_cfg == NULL) {
tr_debug("tr_cfgwatch_create: Allocation failed.");
- } else {
- timerclear(&new_cfg->poll_interval);
- timerclear(&new_cfg->settling_time);
- new_cfg->config_dir=NULL;
- new_cfg->fstat_list=NULL;
- new_cfg->n_files=0;
- new_cfg->change_detected=0;
- timerclear(&new_cfg->last_change_detected);
- new_cfg->ctx=NULL;
- new_cfg->tr=NULL;
- }
-
+ }
talloc_steal(mem_ctx, new_cfg);
talloc_free(tmp_ctx);
return new_cfg;
talloc_free(cfg_status->fstat_list);
cfg_status->n_files=n_files;
cfg_status->fstat_list=fstat_list;
- talloc_steal(cfg_status->ctx, fstat_list);
+ talloc_steal(cfg_status, fstat_list);
goto cleanup;
}
talloc_free(cfg_status->fstat_list);
cfg_status->n_files=n_files;
cfg_status->fstat_list=fstat_list;
- talloc_steal(cfg_status->ctx, fstat_list);
+ talloc_steal(cfg_status, fstat_list);
goto cleanup;
}
}
talloc_free(tmp_ctx);
return update_needed;
}
+
/* must specify the ctx and tr in cfgwatch! */
int tr_read_and_apply_config(TR_CFGWATCH *cfgwatch)
{
retval=1; goto cleanup;
}
- /* allocate a new configuration, dumping an old one if needed */
- if(cfgwatch->tr->new_cfg != NULL)
- tr_cfg_free(cfgwatch->tr->new_cfg);
- cfgwatch->tr->new_cfg=tr_cfg_new(tmp_ctx);
- if (cfgwatch->tr->new_cfg==NULL) {
- tr_debug("tr_read_and_apply_config: Error allocating new_cfg.");
- retval=1; goto cleanup;
- }
- /* now fill it in */
- if (TR_CFG_SUCCESS != (rc = tr_parse_config(cfgwatch->tr->new_cfg, config_dir, n_files, cfg_files))) {
+ /* now fill it in (tr_parse_config allocates space for new config) */
+ if (TR_CFG_SUCCESS != (rc = tr_parse_config(cfgwatch->cfg_mgr, config_dir, n_files, cfg_files))) {
tr_debug("tr_read_and_apply_config: Error parsing configuration information, rc=%d.", rc);
retval=1; goto cleanup;
}
- /* apply initial configuration (frees active_cfg and resets new_cfg to NULL) */
- if (TR_CFG_SUCCESS != (rc = tr_apply_new_config(&cfgwatch->tr->active_cfg,
- &cfgwatch->tr->new_cfg))) {
+ /* apply new configuration (nulls new, manages context ownership) */
+ if (TR_CFG_SUCCESS != (rc = tr_apply_new_config(cfgwatch->cfg_mgr))) {
tr_debug("tr_read_and_apply_config: Error applying configuration, rc = %d.", rc);
retval=1; goto cleanup;
}
- talloc_steal(cfgwatch->ctx, cfgwatch->tr->active_cfg); /* hand over ownership */
/* give ownership of the new_fstat_list to caller's context */
if (cfgwatch->fstat_list != NULL) {
}
cfgwatch->n_files=n_files;
cfgwatch->fstat_list=new_fstat_list;
- talloc_steal(cfgwatch->ctx, new_fstat_list);
+ talloc_steal(cfgwatch, new_fstat_list);
new_fstat_list=NULL;
cleanup:
tr_free_config_file_list(n_files, &cfg_files);
talloc_free(tmp_ctx);
- cfgwatch->tr->new_cfg=NULL; /* this has been freed, either explicitly or with tmp_ctx */
+ cfgwatch->cfg_mgr->new=NULL; /* this has been freed, either explicitly or with tmp_ctx */
return retval;
}
if (tr_cfgwatch_update_needed(cfg_status)) {
tr_notice("Configuration file change detected, waiting for changes to settle.");
- /* if (!cfg_status->change_detected) {*/
- cfg_status->change_detected=1;
+ cfg_status->change_detected=1;
- if (0 != gettimeofday(&cfg_status->last_change_detected, NULL)) {
- tr_err("tr_cfgwatch_event_cb: gettimeofday() failed (1).");
- /* }*/
+ if (0 != gettimeofday(&cfg_status->last_change_detected, NULL)) {
+ tr_err("tr_cfgwatch_event_cb: gettimeofday() failed (1).");
}
}
#include <tr.h>
#include <tid_internal.h>
#include <tr_tid.h>
+#include <tr_trp.h>
#include <tr_config.h>
#include <tr_event.h>
#include <tr_cfgwatch.h>
TR_INSTANCE *tr = NULL;
struct cmdline_args opts;
struct event_base *ev_base;
- struct tr_socket_event tids_ev;
+ struct tr_socket_event tids_ev, trps_ev;
struct event *cfgwatch_ev;
- TR_CFGWATCH *cfgwatch; /* config file watcher status */
/* Use standalone logging */
tr_log_open();
/* process options */
remove_trailing_slash(opts.config_dir);
- /* Get a configuration status object */
- cfgwatch=tr_cfgwatch_create(main_ctx);
- if (cfgwatch == NULL) {
- tr_crit("Unable to create configuration watcher object, exiting.");
- return 1;
- }
-
/***** create a Trust Router instance *****/
- if (NULL == (tr = tr_create())) {
+ if (NULL == (tr = tr_create(main_ctx))) {
tr_crit("Unable to create Trust Router instance, exiting.");
return 1;
}
/***** process configuration *****/
- cfgwatch->config_dir=opts.config_dir;
- cfgwatch->ctx=main_ctx;
- cfgwatch->tr=tr;
- if (0 != tr_read_and_apply_config(cfgwatch)) {
+ tr->cfgwatch=tr_cfgwatch_create(tr);
+ if (tr->cfgwatch == NULL) {
+ tr_crit("Unable to create configuration watcher object, exiting.");
+ return 1;
+ }
+ tr->cfgwatch->config_dir=opts.config_dir;
+ tr->cfgwatch->cfg_mgr=tr->cfg_mgr;
+ if (0 != tr_read_and_apply_config(tr->cfgwatch)) {
tr_crit("Error reading configuration, exiting.");
return 1;
}
/***** initialize the trust path query server instance *****/
- if (0 == (tr->tids = tids_create ())) {
+ if (0 == (tr->tids = tids_create (tr))) {
tr_crit("Error initializing Trust Path Query Server instance.");
return 1;
}
+ /***** initialize the trust router protocol server instance *****/
+ if (0 == (tr->trps = trps_create (tr))) {
+ tr_crit("Error initializing Trust Router Protocol Server instance.");
+ return 1;
+ }
+
/***** Set up the event loop *****/
ev_base=tr_event_loop_init(); /* Set up the event loop */
if (ev_base==NULL) {
}
/* install configuration file watching events */
- cfgwatch->poll_interval=(struct timeval) {1,0}; /* set poll interval in {sec, usec} */
- cfgwatch->settling_time=(struct timeval) {5,0}; /* delay for changes to settle before updating */
-
+ tr->cfgwatch->poll_interval=(struct timeval) {1,0}; /* set poll interval in {sec, usec} */
+ tr->cfgwatch->settling_time=(struct timeval) {5,0}; /* delay for changes to settle before updating */
+ /* TODO: pull these settings out of the configuration files */
+
/* already set config_dir, fstat_list and n_files earlier */
- if (0 != tr_cfgwatch_event_init(ev_base, cfgwatch, &cfgwatch_ev)) {
+ if (0 != tr_cfgwatch_event_init(ev_base, tr->cfgwatch, &cfgwatch_ev)) {
tr_crit("Error initializing configuration file watcher.");
return 1;
}
/*tr_status_event_init();*/ /* install status reporting events */
/* install TID server events */
- if (0 != tr_tids_event_init(ev_base, tr, &tids_ev)) {
+ if (0 != tr_tids_event_init(ev_base,
+ tr->tids,
+ tr->cfg_mgr,
+ &tids_ev)) {
tr_crit("Error initializing Trust Path Query Server instance.");
return 1;
}
- /*tr_trp_event_init();*/ /* install TRP handler events */
+ /* install TRP handler events */
+ if (0 != tr_trps_event_init(ev_base,
+ tr->trps,
+ tr->cfg_mgr,
+ &trps_ev)) {
+ tr_crit("Error initializing Trust Path Query Server instance.");
+ return 1;
+ }
- fflush(stdout); fflush(stderr);
tr_event_loop_run(ev_base); /* does not return until we are done */
- /* TODO: update the cleanup code */
- tids_destroy(tr->tids);
- tr_destroy(tr);
+ /* TODO: ensure talloc is properly used so this actually works */
+ tr_destroy(tr); /* thanks to talloc, should destroy everything */
talloc_free(main_ctx);
return 0;
-#include <tr.h>
#include <tid_internal.h>
#include <tr_filter.h>
#include <tr_comm.h>
#include <tr_event.h>
#include <tr_debug.h>
#include <gsscon.h>
+#include <tr_config.h>
#include <tr_tid.h>
/* Structure to hold TR instance and original request in one cookie */
typedef struct tr_resp_cookie {
- TR_INSTANCE *tr;
+ TIDS_INSTANCE *tids;
TID_REQ *orig_req;
} TR_RESP_COOKIE;
+/* hold a tids instance and a config manager */
+struct tr_tids_event_cookie {
+ TIDS_INSTANCE *tids;
+ TR_CFG_MGR *cfg_mgr;
+};
+
static void tr_tidc_resp_handler (TIDC_INSTANCE *tidc,
TID_REQ *req,
req->resp_rcvd = 1;
/* TBD -- handle concatentation of multiple responses to single req */
- tids_send_response(((TR_RESP_COOKIE *)resp_cookie)->tr->tids,
+ tids_send_response(((TR_RESP_COOKIE *)resp_cookie)->tids,
((TR_RESP_COOKIE *)resp_cookie)->orig_req,
resp);
}
static int tr_tids_req_handler (TIDS_INSTANCE *tids,
- TID_REQ *orig_req,
- TID_RESP *resp,
- void *tr_in)
+ TID_REQ *orig_req,
+ TID_RESP *resp,
+ void *cookie_in)
{
TIDC_INSTANCE *tidc = NULL;
TR_RESP_COOKIE resp_cookie;
TID_REQ *fwd_req = NULL;
TR_COMM *cfg_comm = NULL;
TR_COMM *cfg_apc = NULL;
- TR_INSTANCE *tr = (TR_INSTANCE *) tr_in;
int oaction = TR_FILTER_ACTION_REJECT;
int rc = 0;
time_t expiration_interval;
+ struct tr_tids_event_cookie *cookie=(struct tr_tids_event_cookie *)cookie_in;
+ TR_CFG_MGR *cfg_mgr=cookie->cfg_mgr;
- if ((!tids) || (!orig_req) || (!resp) || (!tr)) {
+ if ((!tids) || (!orig_req) || (!resp)) {
tr_debug("tr_tids_req_handler: Bad parameters");
return -1;
}
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 (tids)
- tids->req_count++;
+ orig_req->realm->buf, orig_req->comm->buf);
+ tids->req_count++;
/* Duplicate the request, so we can modify and forward it */
if (NULL == (fwd_req = tid_dup_req(orig_req))) {
return -1;
}
- if (NULL == (cfg_comm = tr_comm_lookup(tids->cookie, orig_req->comm))) {
+ if (NULL == (cfg_comm = tr_comm_lookup(cfg_mgr->active->comms, orig_req->comm))) {
tr_notice("tr_tids_req_hander: Request for unknown comm: %s.", orig_req->comm->buf);
tids_send_err_response(tids, orig_req, "Unknown community");
return -1;
/* Check that the rp_realm matches the filter for the GSS name that
* was received. */
- if ((!(tr)->rp_gss) ||
- (!(tr)->rp_gss->filter)) {
+ if ((!tids->rp_gss) ||
+ (!tids->rp_gss->filter)) {
tr_notice("tr_tids_req_handler: No GSS name for incoming request.");
tids_send_err_response(tids, orig_req, "No GSS name for request");
return -1;
}
- if ((TR_FILTER_NO_MATCH == tr_filter_process_rp_permitted(orig_req->rp_realm, (tr)->rp_gss->filter, orig_req->cons, &fwd_req->cons, &oaction)) ||
+ if ((TR_FILTER_NO_MATCH == tr_filter_process_rp_permitted(orig_req->rp_realm,
+ tids->rp_gss->filter,
+ orig_req->cons,
+ &fwd_req->cons,
+ &oaction)) ||
(TR_FILTER_ACTION_REJECT == oaction)) {
tr_notice("tr_tids_req_handler: RP realm (%s) does not match RP Realm filter for GSS name", orig_req->rp_realm->buf);
tids_send_err_response(tids, orig_req, "RP Realm filter error");
apc = tr_dup_name(cfg_comm->apcs->id);
/* Check that the APC is configured */
- if (NULL == (cfg_apc = tr_comm_lookup(tids->cookie, apc))) {
+ if (NULL == (cfg_apc = tr_comm_lookup(cfg_mgr->active->comms, apc))) {
tr_notice("tr_tids_req_hander: Request for unknown comm: %s.", apc->buf);
tids_send_err_response(tids, orig_req, "Unknown APC");
return -1;
}
/* Find the AAA server(s) for this request */
- if (NULL == (aaa_servers = tr_idp_aaa_server_lookup(((TR_INSTANCE *)tids->cookie)->active_cfg->idp_realms,
- orig_req->realm,
- orig_req->comm))) {
- tr_debug("tr_tids_req_handler: No AAA Servers for realm %s, defaulting.", orig_req->realm->buf);
- if (NULL == (aaa_servers = tr_default_server_lookup (((TR_INSTANCE *)tids->cookie)->active_cfg->default_servers,
- orig_req->comm))) {
- tr_notice("tr_tids_req_handler: No default AAA servers, discarded.");
- tids_send_err_response(tids, orig_req, "No path to AAA Server(s) for realm");
- return -1;
- }
+ if (NULL == (aaa_servers = tr_idp_aaa_server_lookup(cfg_mgr->active->idp_realms,
+ orig_req->realm,
+ orig_req->comm))) {
+ tr_debug("tr_tids_req_handler: No AAA Servers for realm %s, defaulting.", orig_req->realm->buf);
+ if (NULL == (aaa_servers = tr_default_server_lookup (cfg_mgr->active->default_servers,
+ orig_req->comm))) {
+ tr_notice("tr_tids_req_handler: No default AAA servers, discarded.");
+ tids_send_err_response(tids, orig_req, "No path to AAA Server(s) for realm");
+ return -1;
+ }
} else {
/* if we aren't defaulting, check idp coi and apc membership */
if (NULL == (tr_find_comm_idp(cfg_comm, fwd_req->realm))) {
tidc->client_dh = orig_req->tidc_dh;
/* Save information about this request for the response */
- resp_cookie.tr = tr;
+ resp_cookie.tids = tids;
resp_cookie.orig_req = orig_req;
/* Set-up TID connection */
if (-1 == (fwd_req->conn = tidc_open_connection(tidc,
- aaa_servers->hostname->buf,
- TID_PORT,
- &(fwd_req->gssctx)))) {
+ aaa_servers->hostname->buf,
+ TID_PORT,
+ &(fwd_req->gssctx)))) {
tr_notice("tr_tids_req_handler: Error in tidc_open_connection.");
tids_send_err_response(tids, orig_req, "Can't open connection to next hop TIDS");
return -1;
}
static int tr_tids_gss_handler(gss_name_t client_name, TR_NAME *gss_name,
- void *tr_in)
+ void *data)
{
TR_RP_CLIENT *rp;
- TR_INSTANCE *tr = (TR_INSTANCE *) tr_in;
+ struct tr_tids_event_cookie *cookie=(struct tr_tids_event_cookie *)data;
+ TIDS_INSTANCE *tids = cookie->tids;
+ TR_CFG_MGR *cfg_mgr = cookie->cfg_mgr;
- if ((!client_name) || (!gss_name) || (!tr)) {
+ if ((!client_name) || (!gss_name) || (!tids) || (!cfg_mgr)) {
tr_debug("tr_tidc_gss_handler: Bad parameters.");
return -1;
}
-
+
/* look up the RP client matching the GSS name */
- if ((NULL == (rp = tr_rp_client_lookup(tr->active_cfg->rp_clients, gss_name)))) {
+ if ((NULL == (rp = tr_rp_client_lookup(cfg_mgr->active->rp_clients, gss_name)))) {
tr_debug("tr_tids_gss_handler: Unknown GSS name %s", gss_name->buf);
return -1;
}
- /* Store the rp client in the TR_INSTANCE structure for now...
- * TBD -- fix me for new tasking model. */
- (tr)->rp_gss = rp;
+ /* Store the rp client */
+ tids->rp_gss = rp;
tr_debug("Client's GSS Name: %s", gss_name->buf);
return 0;
/* Configure the tids instance and set up its event handler.
* Returns 0 on success, nonzero on failure. Fills in
- * *tids_event (which should be allocated). */
+ * *tids_event (which should be allocated by caller). */
int tr_tids_event_init(struct event_base *base,
- TR_INSTANCE *tr,
+ TIDS_INSTANCE *tids,
+ TR_CFG_MGR *cfg_mgr,
struct tr_socket_event *tids_ev)
{
+ TALLOC_CTX *tmp_ctx=talloc_new(NULL);
+ struct tr_tids_event_cookie *cookie=NULL;
+ int retval=0;
+
if (tids_ev == NULL) {
tr_debug("tr_tids_event_init: Null tids_ev.");
- return 1;
+ retval=1;
+ goto cleanup;
+ }
+
+ /* Create the cookie for callbacks. We'll put it in the tids context, so it will
+ * be cleaned up when tids is freed by talloc_free. */
+ cookie=talloc(tmp_ctx, struct tr_tids_event_cookie);
+ if (cookie == NULL) {
+ tr_debug("tr_tids_event_init: Unable to allocate cookie.");
+ retval=1;
+ goto cleanup;
}
+ cookie->tids=tids;
+ cookie->cfg_mgr=cfg_mgr;
+ talloc_steal(tids, cookie);
/* get a tids listener */
- tids_ev->sock_fd=tids_get_listener(tr->tids,
+ tids_ev->sock_fd=tids_get_listener(tids,
tr_tids_req_handler,
tr_tids_gss_handler,
- tr->active_cfg->internal->hostname,
- tr->active_cfg->internal->tids_port,
- (void *)tr);
+ cfg_mgr->active->internal->hostname,
+ cfg_mgr->active->internal->tids_port,
+ (void *)cookie);
if (tids_ev->sock_fd < 0) {
tr_crit("Error opening TID server socket.");
- return 1;
+ retval=1;
+ goto cleanup;
}
/* and its event */
tids_ev->sock_fd,
EV_READ|EV_PERSIST,
tr_tids_event_cb,
- (void *)tr->tids);
+ (void *)tids);
event_add(tids_ev->ev, NULL);
- return 0;
+cleanup:
+ talloc_free(tmp_ctx);
+ return retval;
}
--- /dev/null
+#include <fcntl.h>
+#include <event2/event.h>
+#include <talloc.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <gsscon.h>
+#include <tr_rp.h>
+#include <tr_config.h>
+#include <tr_event.h>
+#include <tr_debug.h>
+#include <tr_trp.h>
+
+/* hold a trps instance and a config manager */
+struct tr_trps_event_cookie {
+ TRPS_INSTANCE *trps;
+ TR_CFG_MGR *cfg_mgr;
+};
+
+
+/********** Ersatz TRPS implementation **********/
+TRPS_INSTANCE *trps_create (TALLOC_CTX *mem_ctx)
+{
+ return talloc_zero(mem_ctx, TRPS_INSTANCE);
+}
+
+void trps_destroy (TRPS_INSTANCE *trps)
+{
+ if (trps)
+ talloc_free(trps);
+}
+
+static int trps_listen (TRPS_INSTANCE *trps, int port)
+{
+ int rc = 0;
+ int conn = -1;
+ int optval = 1;
+
+ union {
+ struct sockaddr_storage storage;
+ struct sockaddr_in in4;
+ } addr;
+
+ struct sockaddr_in *saddr = (struct sockaddr_in *) &addr.in4;
+
+ saddr->sin_port = htons (port);
+ saddr->sin_family = AF_INET;
+ saddr->sin_addr.s_addr = INADDR_ANY;
+
+ if (0 > (conn = socket (AF_INET, SOCK_STREAM, 0)))
+ return conn;
+
+ setsockopt(conn, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
+
+ if (0 > (rc = bind (conn, (struct sockaddr *) saddr, sizeof(struct sockaddr_in))))
+ return rc;
+
+ if (0 > (rc = listen(conn, 512)))
+ return rc;
+
+ tr_debug("trps_listen: TRP Server listening on port %d", port);
+ return conn;
+}
+
+#if 0
+
+/* returns EACCES if authorization is denied */
+static int trps_auth_cb(gss_name_t clientName, gss_buffer_t displayName,
+ void *data)
+{
+ TRPS_INSTANCE *inst = (TRPS_INSTANCE *)data;
+ TR_NAME name ={(char *) displayName->value,
+ displayName->length};
+ int result=0;
+
+ if (0!=inst->auth_handler(clientName, &name, inst->cookie)) {
+ tr_debug("trps_auth_cb: client '%.*s' denied authorization.", name.len, name.buf);
+ result=EACCES; /* denied */
+ }
+
+ return result;
+}
+
+/* returns 0 on authorization success, 1 on failure, or -1 in case of error */
+static int trps_auth_connection (TRPS_INSTANCE *inst,
+ int conn,
+ gss_ctx_id_t *gssctx)
+{
+ int rc = 0;
+ int auth, autherr = 0;
+ gss_buffer_desc nameBuffer = {0, NULL};
+ char *name = 0;
+ int nameLen = 0;
+
+ nameLen = asprintf(&name, "trustrouter@%s", inst->hostname);
+ nameBuffer.length = nameLen;
+ nameBuffer.value = name;
+
+ if (rc = gsscon_passive_authenticate(conn, nameBuffer, gssctx, trps_auth_cb, inst)) {
+ tr_debug("trps_auth_connection: Error from gsscon_passive_authenticate(), rc = %d.", rc);
+ return -1;
+ }
+
+ if (rc = gsscon_authorize(*gssctx, &auth, &autherr)) {
+ tr_debug("trps_auth_connection: Error from gsscon_authorize, rc = %d, autherr = %d.",
+ rc, autherr);
+ return -1;
+ }
+
+ if (auth)
+ tr_debug("trps_auth_connection: Connection authenticated, conn = %d.", conn);
+ else
+ tr_debug("trps_auth_connection: Authentication failed, conn %d.", conn);
+
+ return !auth;
+}
+#endif
+
+static int tr_trps_req_handler (TRPS_INSTANCE *trps,
+ TRP_REQ *orig_req,
+ TRP_RESP *resp,
+ void *tr_in)
+{
+ if (orig_req != NULL)
+ free(orig_req);
+ return -1; /* not handling anything right now */
+}
+
+static void trps_handle_connection (TRPS_INSTANCE *trps, int conn)
+{
+ return;
+}
+
+static int tr_trps_gss_handler(gss_name_t client_name, TR_NAME *gss_name,
+ void *cookie_in)
+{
+ TR_RP_CLIENT *rp;
+ struct tr_trps_event_cookie *cookie=(struct tr_trps_event_cookie *)cookie_in;
+ TRPS_INSTANCE *trps = cookie->trps;
+ TR_CFG_MGR *cfg_mgr = cookie->cfg_mgr;
+
+ tr_debug("tr_trps_gss_handler()");
+
+ if ((!client_name) || (!gss_name) || (!trps) || (!cfg_mgr)) {
+ tr_debug("tr_trps_gss_handler: Bad parameters.");
+ return -1;
+ }
+
+ /* look up the RP client matching the GSS name */
+ if ((NULL == (rp = tr_rp_client_lookup(cfg_mgr->active->rp_clients, gss_name)))) {
+ tr_debug("tr_trps_gss_handler: Unknown GSS name %s", gss_name->buf);
+ return -1;
+ }
+
+ trps->rp_gss = rp;
+ tr_debug("Client's GSS Name: %s", gss_name->buf);
+
+ return 0;
+}
+
+
+static int trps_get_listener(TRPS_INSTANCE *trps,
+ TRPS_REQ_FUNC *req_handler,
+ trps_auth_func *auth_handler,
+ const char *hostname,
+ unsigned int port,
+ void *cookie)
+{
+ int listen = -1;
+
+ if (0 > (listen = trps_listen(trps, port))) {
+ char errbuf[256];
+ if (0 == strerror_r(errno, errbuf, 256)) {
+ tr_debug("trps_get_listener: Error opening port %d: %s.", port, errbuf);
+ } else {
+ tr_debug("trps_get_listener: Unknown error openining port %d.", port);
+ }
+ }
+
+ if (listen > 0) {
+ /* opening port succeeded */
+ tr_debug("trps_get_listener: Opened port %d.", port);
+
+ /* make this socket non-blocking */
+ if (0 != fcntl(listen, F_SETFL, O_NONBLOCK)) {
+ tr_debug("trps_get_listener: Error setting O_NONBLOCK.");
+ close(listen);
+ listen=-1;
+ }
+ }
+
+ if (listen > 0) {
+ /* store the caller's request handler & cookie */
+ trps->req_handler = req_handler;
+ trps->auth_handler = auth_handler;
+ trps->hostname = talloc_strdup(trps, hostname);
+ trps->port = port;
+ trps->cookie = cookie;
+ }
+
+ return listen;
+}
+
+
+/* Accept and process a connection on a port opened with trps_get_listener() */
+int trps_accept(TRPS_INSTANCE *trps, int listen)
+{
+ int conn=-1;
+
+ conn = accept(listen, NULL, NULL);
+
+ if (0 > conn) {
+ perror("Error from TRP Server accept()");
+ return 1;
+ }
+
+ /* does not fork, handles request in main process */
+ trps_handle_connection(trps, conn);
+ write(conn, "TRP Online\n", strlen("TRP Online\n"));
+ close(conn);
+ return 0;
+}
+
+
+/********** Event Handling **********/
+
+/* called when a connection to the TRPS port is received */
+static void tr_trps_event_cb(int listener, short event, void *arg)
+{
+ TRPS_INSTANCE *trps = (TRPS_INSTANCE *)arg;
+
+ if (0==(event & EV_READ))
+ tr_debug("tr_trps_event_cb: unexpected event on TRPS socket (event=0x%X)", event);
+ else
+ trps_accept(trps, listener);
+}
+
+
+/* Configure the trps instance and set up its event handler.
+ * Returns 0 on success, nonzero on failure. Fills in
+ * *trps_event (which should be allocated by caller). */
+int tr_trps_event_init(struct event_base *base,
+ TRPS_INSTANCE *trps,
+ TR_CFG_MGR *cfg_mgr,
+ struct tr_socket_event *trps_ev)
+{
+ TALLOC_CTX *tmp_ctx=talloc_new(NULL);
+ struct tr_trps_event_cookie *cookie;
+ int retval=0;
+
+ if (trps_ev == NULL) {
+ tr_debug("tr_trps_event_init: Null trps_ev.");
+ retval=1;
+ goto cleanup;
+ }
+
+ /* Create the cookie for callbacks. It is part of the trps context, so it will
+ * be cleaned up when trps is freed by talloc_free. */
+ cookie=talloc(tmp_ctx, struct tr_trps_event_cookie);
+ if (cookie == NULL) {
+ tr_debug("tr_trps_event_init: Unable to allocate cookie.");
+ retval=1;
+ goto cleanup;
+ }
+ cookie->trps=trps;
+ cookie->cfg_mgr=cfg_mgr;
+ talloc_steal(trps, cookie);
+
+ /* get a trps listener */
+ trps_ev->sock_fd=trps_get_listener(trps,
+ tr_trps_req_handler,
+ tr_trps_gss_handler,
+ cfg_mgr->active->internal->hostname,
+ cfg_mgr->active->internal->trps_port,
+ (void *)cookie);
+ if (trps_ev->sock_fd < 0) {
+ tr_crit("Error opening TRP server socket.");
+ retval=1;
+ goto cleanup;
+ }
+
+ /* and its event */
+ trps_ev->ev=event_new(base,
+ trps_ev->sock_fd,
+ EV_READ|EV_PERSIST,
+ tr_trps_event_cb,
+ (void *)trps);
+ event_add(trps_ev->ev, NULL);
+
+cleanup:
+ talloc_free(tmp_ctx);
+ return retval;
+}