common/tr_debug.c \
common/tr_util.c
+tid_srcs = trp/trpc.c \
+tid/tid_resp.c \
+tid/tid_req.c \
+tid/tids.c \
+tid/tidc.c
+
+trp_srcs = trp/trp_upd.c \
+trp/trp_req.c \
+trp/trp_conn.c \
+trp/trps.c
+
check_PROGRAMS = common/t_constraint
TESTS = common/t_constraint
-lib_LTLIBRARIES = libtr_tid.la
+#lib_LTLIBRARIES = libtr_tid.la libtr_trp.la
common_t_constraint_SOURCES = common/t_constraint.c
common_t_constraint_CPPFLAGS = $(AM_CPPFLAGS) -DTESTS=\"$(srcdir)/common/tests.json\"
common_t_constraint_LDADD = gsscon/libgsscon.la libtr_tid.la
-tr_trust_router_SOURCES = tr/tr_main.c \
+tr_trust_router_SOURCES = $(common_srcs) \
+tr/tr_main.c \
common/tr_config.c \
common/tr_idp.c \
common/tr_comm.c \
common/tr_filter.c \
common/tr_rp.c \
+common/tr_mq.c \
tr/tr.c \
tr/tr_event.c \
tr/tr_cfgwatch.c \
tr/tr_tid.c \
-tr/tr_trp.c
+tr/tr_trp.c \
+$(trp_srcs) \
+$(tid_srcs)
-tr_trust_router_LDADD = gsscon/libgsscon.la libtr_tid.la $(GLIB_LIBS)
+tr_trust_router_CFLAGS = $(AM_CFLAGS) -pthread
+tr_trust_router_LDFLAGS = $(AM_LDFLAGS) -levent_pthreads
+#tr_trust_router_LDADD = gsscon/libgsscon.la libtr_tid.la libtr_trp.la $(GLIB_LIBS)
+tr_trust_router_LDADD = gsscon/libgsscon.la $(GLIB_LIBS)
-tr_trpc_SOURCES = tr/trpc_main.c \
+tr_trpc_SOURCES = $(common_srcs) \
+tr/trpc_main.c \
common/tr_rp.c \
-tr/tr_trp.c
+common/tr_mq.c \
+tr/tr_trp.c \
+$(trp_srcs) \
+$(tid_srcs)
-tr_trpc_LDADD = gsscon/libgsscon.la libtr_tid.la $(GLIB_LIBS)
+#tr_trpc_LDADD = gsscon/libgsscon.la libtr_tid.la libtr_trp.la $(GLIB_LIBS)
+tr_trpc_LDADD = gsscon/libgsscon.la $(GLIB_LIBS)
trp_msgtst_SOURCES = trp/msgtst.c \
trp/trp_upd.c \
common/tr_config.c \
common/tr_debug.c
-trp_msgtst_LDADD = libtr_tid.la $(GLIB_LIBS)
+#trp_msgtst_LDADD = libtr_tid.la $(GLIB_LIBS)
+trp_msgtst_LDADD = $(GLIB_LIBS)
tid_example_tidc_SOURCES = tid/example/tidc_main.c
-tid_example_tidc_LDADD = gsscon/libgsscon.la libtr_tid.la $(GLIB_LIBS)
+#tid_example_tidc_LDADD = gsscon/libgsscon.la libtr_tid.la $(GLIB_LIBS)
+tid_example_tidc_LDADD = gsscon/libgsscon.la $(GLIB_LIBS)
tid_example_tids_SOURCES = tid/example/tids_main.c
-tid_example_tids_LDADD = gsscon/libgsscon.la libtr_tid.la $(GLIB_LIBS)
+#tid_example_tids_LDADD = gsscon/libgsscon.la libtr_tid.la $(GLIB_LIBS)
+tid_example_tids_LDADD = gsscon/libgsscon.la $(GLIB_LIBS)
common_dh_test_tr_dh_test_SOURCES = common/tr_dh.c \
common/tr_debug.c \
common/mq_test/mq_test.c
common_mq_test_mq_test_CFLAGS = -pthread
-common_mq_test_mq_test_LDFLAGS = -pthread -ltalloc
+common_mq_test_mq_test_LDFLAGS = $(AM_LDFLAGS) -ltalloc
common_mq_test_thread_test_SOURCES = common/tr_mq.c \
common/tr_debug.c \
common/mq_test/thread_test.c
common_mq_test_thread_test_CFLAGS = -pthread
-common_mq_test_thread_test_LDFLAGS = -pthread -ltalloc
-
-libtr_tid_la_SOURCES = tid/tids.c tid/tidc.c tid/tid_req.c tid/tid_resp.c \
-$(common_srcs)
-
-libtr_tid_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden
-libtr_tid_la_LIBADD = gsscon/libgsscon.la $(GLIB_LIBS)
-libtr_tid_la_LDFLAGS = $(AM_LDFLAGS) -version-info 2 -no-undefined
+common_mq_test_thread_test_LDFLAGS = $(AM_LDFLAGS) -ltalloc
+
+# libtr_tid_la_SOURCES = tid/tids.c tid/tidc.c tid/tid_req.c tid/tid_resp.c \
+# $(common_srcs)
+#
+# libtr_tid_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden
+# libtr_tid_la_LIBADD = gsscon/libgsscon.la $(GLIB_LIBS)
+# libtr_tid_la_LDFLAGS = $(AM_LDFLAGS) -version-info 2 -no-undefined
+#
+# libtr_trp_la_SOURCES = trp/trps.c trp/trpc.c trp/trp_req.c trp/trp_upd.c trp/trp_conn.c \
+# $(common_srcs)
+#
+# libtr_trp_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden
+# libtr_trp_la_LIBADD = gsscon/libgsscon.la $(GLIB_LIBS)
+# libtr_trp_la_LDFLAGS = $(AM_LDFLAGS) -version-info 2 -no-undefined
pkginclude_HEADERS = include/trust_router/tid.h include/trust_router/tr_name.h \
include/tr_debug.h \
msg->next=next;
}
-static TR_MQ_MSG *tr_mq_msg_get_tail(TR_MQ_MSG *msg)
-{
- while (msg!=NULL)
- msg=tr_mq_msg_get_next(msg);
- return msg;
-}
-
-static void tr_mq_msg_append(TR_MQ_MSG *msg, TR_MQ_MSG *new)
-{
- tr_mq_msg_set_next(tr_mq_msg_get_tail(msg), new);
-}
-
/* Message Queues */
TR_MQ *tr_mq_new(TALLOC_CTX *mem_ctx)
{
return pthread_mutex_lock(&(mq->mutex));
}
-static TR_MQ_MST *tr_mq_get_head(TR_MQ *mq)
+static TR_MQ_MSG *tr_mq_get_head(TR_MQ *mq)
{
return mq->head;
}
mq->head=msg;
}
-static TR_MQ_MST *tr_mq_get_tail(TR_MQ *mq)
+static TR_MQ_MSG *tr_mq_get_tail(TR_MQ *mq)
{
return mq->tail;
}
mq->tail=msg;
}
+void tr_mq_set_notify_cb(TR_MQ *mq, TR_MQ_NOTIFY_FN cb, void *arg)
+{
+ mq->notify_cb=cb;
+ mq->notify_cb_arg=arg;
+}
+
+
/* puts msg in mq's talloc context */
void tr_mq_append(TR_MQ *mq, TR_MQ_MSG *msg)
{
- int was_empty=FALSE;
+ int was_empty=0;
TR_MQ_NOTIFY_FN notify_cb=NULL;
void *notify_cb_arg=NULL;
tr_mq_lock(mq);
if (tr_mq_get_head(mq)==NULL) {
- was_empty=TRUE;
+ was_empty=1;
tr_mq_set_head(mq, msg);
tr_mq_set_tail(mq, msg);
} else {
- tr_mq_msg_set_next(tr_mq_get_tail(), msg); /* add to list */
+ tr_mq_msg_set_next(tr_mq_get_tail(mq), msg); /* add to list */
tr_mq_set_tail(mq, msg); /* update tail of list */
}
talloc_steal(mq, msg);
#include <talloc.h>
#include <pthread.h>
-/* REMOVE */
-#define FALSE 0
-#define TRUE 1
-
/* msg for inter-thread messaging */
typedef struct tr_mq_msg TR_MQ_MSG;
struct tr_mq_msg {
void tr_mq_free(TR_MQ *mq);
int tr_mq_lock(TR_MQ *mq);
int tr_mq_unlock(TR_MQ *mq);
-void tr_mq_set_notify_cb(TR_MQ *mq, TR_MQ_NOTIFY_FN cb);
+void tr_mq_set_notify_cb(TR_MQ *mq, TR_MQ_NOTIFY_FN cb, void *arg);
void tr_mq_append(TR_MQ *mq, TR_MQ_MSG *msg);
TR_MQ_MSG *tr_mq_pop(TR_MQ *mq);
#define TR_TRP_H
#include <talloc.h>
+#include <pthread.h>
#include <trp_internal.h>
#include <tr_config.h>
#include <tr_event.h>
-/* Data for a TRP peer */
-typedef struct tr_trp_peer {
- TRPS_INSTANCE *trps; /* incoming connection, may be null */
- TRPC_INSTANCE *trpc; /* outgoing connection, may be null */
-} TR_TRP_PEER;
-
/* prototypes */
int tr_trps_event_init(struct event_base *base, TRPS_INSTANCE *trps, TR_CFG_MGR *cfg_mgr,
struct tr_socket_event *trps_ev);
#ifndef TRP_INTERNAL_H
#define TRP_INTERNAL_H
+#include <pthread.h>
#include <talloc.h>
#include <gsscon.h>
#include <trust_router/tr_dh.h>
+#include <tr_mq.h>
#include <trust_router/trp.h>
/* info records */
-typedef enum trp_inforec_type {
- TRP_INFOREC_TYPE_UNKNOWN=0, /* conveniently, JSON parser returns 0 if a non-integer number is specified */
- TRP_INFOREC_TYPE_ROUTE,
- TRP_INFOREC_TYPE_COMMUNITY, /* not yet implemented (2016-06-14) */
-} TRP_INFOREC_TYPE;
-
/* TRP update record types */
typedef struct trp_inforec_route {
TR_NAME *comm;
/* TRP_INFOREC_COMM *comm; */
} TRP_INFOREC_DATA;
-typedef struct trp_inforec TRP_INFOREC;
struct trp_inforec {
TRP_INFOREC *next;
TRP_INFOREC_TYPE type;
TR_NAME *realm;
};
-TRP_UPD *trp_upd_new(TALLOC_CTX *mem_ctx);
-void trp_upd_free(TRP_UPD *update);
-TRP_INFOREC *trp_upd_get_inforec(TRP_UPD *upd);
-void trp_upd_set_inforec(TRP_UPD *upd, TRP_INFOREC *rec);
-TRP_INFOREC *trp_inforec_new(TALLOC_CTX *mem_ctx, TRP_INFOREC_TYPE type);
-void trp_inforec_free(TRP_INFOREC *rec);
-TRP_INFOREC *trp_inforec_get_next(TRP_INFOREC *rec);
-void trp_inforec_set_next(TRP_INFOREC *rec, TRP_INFOREC *next_rec);
-TRP_INFOREC_TYPE trp_inforec_get_type(TRP_INFOREC *rec);
-void trp_inforec_set_type(TRP_INFOREC *rec, TRP_INFOREC_TYPE type);
-TR_NAME *trp_inforec_get_comm(TRP_INFOREC *rec);
-TRP_RC trp_inforec_set_comm(TRP_INFOREC *rec, TR_NAME *comm);
-TR_NAME *trp_inforec_get_realm(TRP_INFOREC *rec);
-TRP_RC trp_inforec_set_realm(TRP_INFOREC *rec, TR_NAME *realm);
-TR_NAME *trp_inforec_get_trust_router(TRP_INFOREC *rec);
-TRP_RC trp_inforec_set_trust_router(TRP_INFOREC *rec, TR_NAME *trust_router);
-unsigned int trp_inforec_get_metric(TRP_INFOREC *rec);
-TRP_RC trp_inforec_set_metric(TRP_INFOREC *rec, unsigned int metric);
-unsigned int trp_inforec_get_interval(TRP_INFOREC *rec);
-TRP_RC trp_inforec_set_interval(TRP_INFOREC *rec, unsigned int interval);
-TRP_INFOREC_TYPE trp_inforec_type_from_string(const char *s);
-const char *trp_inforec_type_to_string(TRP_INFOREC_TYPE msgtype);
-
-
-TRP_REQ *trp_req_new(TALLOC_CTX *mem_ctx);
-void trp_req_free(TRP_REQ *req);
-TR_NAME *trp_req_get_comm(TRP_REQ *req);
-void trp_req_set_comm(TRP_REQ *req, TR_NAME *comm);
-TR_NAME *trp_req_get_realm(TRP_REQ *req);
-void trp_req_set_realm(TRP_REQ *req, TR_NAME *realm);
typedef struct trps_instance TRPS_INSTANCE;
-typedef int (TRPS_REQ_FUNC)();
-typedef void (TRPS_RESP_FUNC)();
-typedef int (trps_auth_func)(gss_name_t client_name, TR_NAME *display_name, void *cookie);
-
-
-/* encapsulate a gss context and its connection file handle */
-typedef struct trps_connection {
- int conn;
+typedef int (*TRP_REQ_FUNC)();
+typedef void (*TRP_RESP_FUNC)();
+/*typedef int (*TRP_AUTH_FUNC)(gss_name_t client_name, TR_NAME *display_name, void *cookie);*/
+typedef client_cb_fn TRP_AUTH_FUNC;
+
+typedef enum trp_connection_status {
+ TRP_CONNECTION_DOWN=0,
+ TRP_CONNECTION_UP,
+} TRP_CONNECTION_STATUS;
+
+typedef struct trp_connection TRP_CONNECTION;
+struct trp_connection {
+ TRP_CONNECTION *next;
+ pthread_t *thread; /* thread servicing this connection */
+ int fd;
+ TR_NAME *gssname;
gss_ctx_id_t *gssctx;
-} TRPS_CONNECTION;
-
-/* a collection of the above */
-#define TRPS_CONNECTIONS_MAX 10
-typedef struct trps_connection_set {
- TRPS_CONNECTION *conn[TRPS_CONNECTIONS_MAX];
- unsigned int nconn;
-} TRPS_CONNECTION_SET;
+ TRP_CONNECTION_STATUS status;
+ pthread_mutex_t status_mutex;
+};
/* TRP Client Instance Data */
typedef struct trpc_instance {
+ TRP_CONNECTION *conn;
DH *client_dh; /* Client's DH struct with priv and pub keys */
} TRPC_INSTANCE;
struct trps_instance {
char *hostname;
unsigned int port;
- TRPS_REQ_FUNC *req_handler;
- trps_auth_func *auth_handler;
+ TRP_AUTH_FUNC auth_handler;
+ TRP_REQ_FUNC req_handler;
void *cookie;
- struct tr_rp_client *rp_gss; /* Client matching GSS name, TBD -- FIX ME (??) */
- TRPS_CONNECTION_SET *connections; /* active GSS connections */
+ TRP_CONNECTION *conn; /* connections to peers */
+ TR_MQ *mq;
};
-typedef enum {
- TRPS_ERR_OK=0, /* success */
- TRPS_ERR_NOMEM, /* allocation problem */
- TRPS_ERR_MAX_CONN, /* out of connections */
- TRPS_ERR_UNKNOWN /* catch-all */
-} TRPS_ERR;
-
-/* prototypes */
-
-/* these should probably be static? */
-TRPS_CONNECTION *trps_connection_new(TALLOC_CTX *mem_ctx);
-TRPS_CONNECTION_SET *trps_connection_set_new(TALLOC_CTX *mem_ctx);
-TRPS_ERR trps_connection_set_add(TRPS_CONNECTION_SET *tcs, TRPS_CONNECTION *new_conn);
-TRPS_ERR trps_connection_set_del(TRPS_CONNECTION_SET *tcs, TRPS_CONNECTION *conn);
-unsigned int trps_connection_set_len(TRPS_CONNECTION_SET *tcs);
-TRPC_INSTANCE *trpc_create (TALLOC_CTX *mem_ctx);
-void trpc_destroy (TRPC_INSTANCE *trpc);
+TRP_CONNECTION *trp_connection_new(TALLOC_CTX *mem_ctx);
+void trp_connection_free(TRP_CONNECTION *conn);
+int trp_connection_get_fd(TRP_CONNECTION *conn);
+void trp_connection_set_fd(TRP_CONNECTION *conn, int fd);
+TR_NAME *trp_connection_get_gssname(TRP_CONNECTION *conn);
+void trp_connection_set_gssname(TRP_CONNECTION *conn, TR_NAME *gssname);
+gss_ctx_id_t *trp_connection_get_gssctx(TRP_CONNECTION *conn);
+void trp_connection_set_gssctx(TRP_CONNECTION *conn, gss_ctx_id_t *gssctx);
+TRP_CONNECTION_STATUS trp_connection_get_status(TRP_CONNECTION *conn);
+void trp_connection_set_status(TRP_CONNECTION *conn, TRP_CONNECTION_STATUS status);
+pthread_t *trp_connection_get_thread(TRP_CONNECTION *conn);
+void trp_connection_set_thread(TRP_CONNECTION *conn, pthread_t *thread);
+TRP_CONNECTION *trp_connection_get_next(TRP_CONNECTION *conn);
+void trp_connection_append(TRP_CONNECTION *conn, TRP_CONNECTION *new);
+int trp_connection_auth(TRP_CONNECTION *conn, TRP_AUTH_FUNC auth_callback, void *callback_data);
+TRP_CONNECTION *trp_connection_accept(TALLOC_CTX *mem_ctx, int listen, TR_NAME *gssname,
+ TRP_AUTH_FUNC auth_callback, TRP_REQ_FUNC req_handler,
+ void *callback_data);
+
+TRPC_INSTANCE *trpc_new (TALLOC_CTX *mem_ctx);
+void trpc_free (TRPC_INSTANCE *trpc);
int trpc_open_connection (TRPC_INSTANCE *trpc, char *server, unsigned int port, gss_ctx_id_t *gssctx);
int trpc_send_msg (TRPC_INSTANCE *trpc, int conn, gss_ctx_id_t gssctx, const char *msg_content,
int *resp_handler(), void *cookie);
-TRPS_INSTANCE *trps_create (TALLOC_CTX *mem_ctx);
-void trps_destroy (TRPS_INSTANCE *trps);
+TRPS_INSTANCE *trps_new (TALLOC_CTX *mem_ctx);
+void trps_free (TRPS_INSTANCE *trps);
int trps_send_msg (TRPS_INSTANCE *trps, int conn, gss_ctx_id_t gssctx, const char *msg_content);
int trps_accept(TRPS_INSTANCE *trps, int listen);
+void trps_add_connection(TRPS_INSTANCE *trps, TRP_CONNECTION *new);
+int trps_get_listener(TRPS_INSTANCE *trps,
+ TRP_REQ_FUNC req_handler,
+ TRP_AUTH_FUNC auth_handler,
+ const char *hostname,
+ unsigned int port,
+ void *cookie);
+int trps_auth_cb(gss_name_t clientName, gss_buffer_t displayName, void *data);
#endif /* TRP_INTERNAL_H */
TRP_UNSUPPORTED, /* unsupported feature */
} TRP_RC;
+typedef enum trp_inforec_type {
+ TRP_INFOREC_TYPE_UNKNOWN=0, /* conveniently, JSON parser returns 0 if a non-integer number is specified */
+ TRP_INFOREC_TYPE_ROUTE,
+ TRP_INFOREC_TYPE_COMMUNITY, /* not yet implemented (2016-06-14) */
+} TRP_INFOREC_TYPE;
+
+typedef struct trp_inforec TRP_INFOREC;
typedef struct trp_update TRP_UPD;
typedef struct trp_req TRP_REQ;
+/* Functions for TRP_UPD structures */
+TR_EXPORT TRP_UPD *trp_upd_new(TALLOC_CTX *mem_ctx);
+void trp_upd_free(TRP_UPD *update);
+TR_EXPORT TRP_INFOREC *trp_upd_get_inforec(TRP_UPD *upd);
+void trp_upd_set_inforec(TRP_UPD *upd, TRP_INFOREC *rec);
+TR_EXPORT TRP_INFOREC *trp_inforec_new(TALLOC_CTX *mem_ctx, TRP_INFOREC_TYPE type);
+void trp_inforec_free(TRP_INFOREC *rec);
+TR_EXPORT TRP_INFOREC *trp_inforec_get_next(TRP_INFOREC *rec);
+void trp_inforec_set_next(TRP_INFOREC *rec, TRP_INFOREC *next_rec);
+TR_EXPORT TRP_INFOREC_TYPE trp_inforec_get_type(TRP_INFOREC *rec);
+void trp_inforec_set_type(TRP_INFOREC *rec, TRP_INFOREC_TYPE type);
+TR_EXPORT TR_NAME *trp_inforec_get_comm(TRP_INFOREC *rec);
+TRP_RC trp_inforec_set_comm(TRP_INFOREC *rec, TR_NAME *comm);
+TR_EXPORT TR_NAME *trp_inforec_get_realm(TRP_INFOREC *rec);
+TRP_RC trp_inforec_set_realm(TRP_INFOREC *rec, TR_NAME *realm);
+TR_EXPORT TR_NAME *trp_inforec_get_trust_router(TRP_INFOREC *rec);
+TRP_RC trp_inforec_set_trust_router(TRP_INFOREC *rec, TR_NAME *trust_router);
+TR_EXPORT unsigned int trp_inforec_get_metric(TRP_INFOREC *rec);
+TRP_RC trp_inforec_set_metric(TRP_INFOREC *rec, unsigned int metric);
+TR_EXPORT unsigned int trp_inforec_get_interval(TRP_INFOREC *rec);
+TRP_RC trp_inforec_set_interval(TRP_INFOREC *rec, unsigned int interval);
+TR_EXPORT TRP_INFOREC_TYPE trp_inforec_type_from_string(const char *s);
+TR_EXPORT const char *trp_inforec_type_to_string(TRP_INFOREC_TYPE msgtype);
+
+/* Functions for TRP_REQ structures */
+TR_EXPORT TRP_REQ *trp_req_new(TALLOC_CTX *mem_ctx);
+TR_EXPORT void trp_req_free(TRP_REQ *req);
+TR_EXPORT TR_NAME *trp_req_get_comm(TRP_REQ *req);
+void trp_req_set_comm(TRP_REQ *req, TR_NAME *comm);
+TR_EXPORT TR_NAME *trp_req_get_realm(TRP_REQ *req);
+void trp_req_set_realm(TRP_REQ *req, TR_NAME *realm);
+
#endif /* TRP_H */
#include <jansson.h>
#include <argp.h>
#include <event2/event.h>
+#include <event2/thread.h>
#include <talloc.h>
#include <sys/time.h>
#include <tr_cfgwatch.h>
#include <tr_debug.h>
+#define TALLOC_DEBUG_ENABLE 1
+
/***** command-line option handling / setup *****/
/* Strip trailing / from a path name.*/
static struct argp argp = {cmdline_options, parse_option, arg_doc, doc};
-int main (int argc, char *argv[])
+/***** talloc error handling *****/
+/* called when talloc tries to abort */
+static void tr_abort(const char *reason)
+{
+ tr_crit("tr_abort: Critical error, talloc aborted. Reason: %s", reason);
+ abort();
+}
+
+#if TALLOC_DEBUG_ENABLE
+static void tr_talloc_log(const char *msg)
+{
+ tr_debug("talloc: %s", msg);
+}
+#endif /* TALLOC_DEBUG_ENABLE */
+
+int main(int argc, char *argv[])
{
- TALLOC_CTX *main_ctx=talloc_new(NULL);
+ TALLOC_CTX *main_ctx=NULL;
TR_INSTANCE *tr = NULL;
struct cmdline_args opts;
struct tr_socket_event tids_ev, trps_ev;
struct event *cfgwatch_ev;
+ /* we're going to be multithreaded, so disable null context tracking */
+ talloc_set_abort_fn(tr_abort);
+ talloc_disable_null_tracking();
+#if TALLOC_DEBUG_ENABLE
+ talloc_set_log_fn(tr_talloc_log);
+#endif /* TALLOC_DEBUG_ENABLE */
+ main_ctx=talloc_new(NULL);
+
/* Use standalone logging */
tr_log_open();
}
/***** initialize the trust path query server instance *****/
- if (0 == (tr->tids = tids_create (tr))) {
+ if (NULL == (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))) {
+ if (NULL == (tr->trps = trps_new(tr))) {
tr_crit("Error initializing Trust Router Protocol Server instance.");
return 1;
}
/***** Set up the event loop *****/
+ evthread_use_pthreads(); /* enable pthreads support */
ev_base=tr_event_loop_init(); /* Set up the event loop */
if (ev_base==NULL) {
tr_crit("Error initializing event loop.");
+#include <pthread.h>
#include <fcntl.h>
#include <event2/event.h>
#include <talloc.h>
static int tr_trps_req_handler (TRPS_INSTANCE *trps,
TRP_REQ *orig_req,
- TRP_RESP *resp,
void *tr_in)
{
if (orig_req != NULL)
}
-static int tr_trps_gss_handler(gss_name_t client_name, TR_NAME *gss_name,
+static int tr_trps_gss_handler(gss_name_t client_name, gss_buffer_t 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_NAME name={gss_name->value, gss_name->length};
tr_debug("tr_trps_gss_handler()");
}
/* 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);
+ if ((NULL == (rp = tr_rp_client_lookup(cfg_mgr->active->rp_clients, &name)))) {
+ tr_debug("tr_trps_gss_handler: Unknown GSS name %.*s", name.len, name.buf);
return -1;
}
- trps->rp_gss = rp;
- tr_debug("Client's GSS Name: %s", gss_name->buf);
+ /*trps->rp_gss = rp;*/
+ tr_debug("Client's GSS Name: %.*s", name.len, name.buf);
return 0;
}
+/* data passed to thread */
+struct thread_data {
+ TRP_CONNECTION *conn;
+ TRPS_INSTANCE *trps;
+};
+/* thread to handle GSS connections to peers */
+static void *tr_trps_conn_thread(void *arg)
+{
+ struct thread_data *thread_data=talloc_get_type_abort(arg, struct thread_data);
+ TRP_CONNECTION *conn=thread_data->conn;
+ TRPS_INSTANCE *trps=thread_data->trps;
+
+ tr_debug("tr_trps_conn_thread: started");
+ /* try to establish a GSS context */
+ if (0!=trp_connection_auth(conn, trps->auth_handler, trps->cookie)) {
+ tr_notice("tr_trps_conn_thread: failed to authorize connection");
+ pthread_exit(NULL);
+ }
+ tr_notice("tr_trps_conn_thread: authorized connection");
+ return NULL;
+}
+
/* 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;
- int conn=-1;
+ TALLOC_CTX *tmp_ctx=talloc_new(NULL);
+ TRPS_INSTANCE *trps = talloc_get_type_abort(arg, TRPS_INSTANCE); /* aborts on wrong type */
+ TRP_CONNECTION *conn=NULL;
+ TR_NAME *gssname=NULL;
+ char *name=NULL;
+ struct thread_data *thread_data;
if (0==(event & EV_READ)) {
tr_debug("tr_trps_event_cb: unexpected event on TRPS socket (event=0x%X)", event);
} else {
- conn=trps_accept(trps, listener);
- if (conn>0) {
+ /* create a thread to handle this connection */
+ asprintf(&name, "trustrouter@%s", trps->hostname);
+ gssname=tr_new_name(name);
+ free(name); name=NULL;
+ conn=trp_connection_accept(tmp_ctx, listener, gssname, trps_auth_cb, NULL, trps);
+ if (conn!=NULL) {
/* need to monitor this fd and trigger events when read becomes possible */
+ thread_data=talloc(conn, struct thread_data);
+ if (thread_data==NULL) {
+ tr_err("tr_trps_event_cb: unable to allocate thread_data");
+ talloc_free(tmp_ctx);
+ return;
+ }
+ thread_data->conn=conn;
+ thread_data->trps=trps;
+ pthread_create(conn->thread, NULL, tr_trps_conn_thread, thread_data);
+ trps_add_connection(trps, conn); /* remember the connection */
}
}
+ talloc_free(tmp_ctx);
}
talloc_free(tmp_ctx);
return retval;
}
+
printf("TRPC Client:\nServer = %s, port = %i\n", opts.server, opts.port);
/* Create a TRP client instance & the client DH */
- trpc = trpc_create(main_ctx);
+ trpc = trpc_new(main_ctx);
if (NULL == (trpc->client_dh = tr_create_dh_params(NULL, 0))) {
printf("Error creating client DH params.\n");
return 1;
}
/* Clean-up the TRP client instance, and exit */
- trpc_destroy(trpc);
+ trpc_free(trpc);
return 0;
}
--- /dev/null
+#include <gsscon.h>
+#include <fcntl.h>
+#include <talloc.h>
+#include <unistd.h>
+
+#include <tr_debug.h>
+#include <trp_internal.h>
+
+int trp_connection_get_fd(TRP_CONNECTION *conn)
+{
+ return conn->fd;
+}
+
+void trp_connection_set_fd(TRP_CONNECTION *conn, int fd)
+{
+ conn->fd=fd;
+}
+
+TR_NAME *trp_connection_get_gssname(TRP_CONNECTION *conn)
+{
+ return conn->gssname;
+}
+
+void trp_connection_set_gssname(TRP_CONNECTION *conn, TR_NAME *gssname)
+{
+ conn->gssname=gssname;
+}
+
+gss_ctx_id_t *trp_connection_get_gssctx(TRP_CONNECTION *conn)
+{
+ return conn->gssctx;
+}
+
+void trp_connection_set_gssctx(TRP_CONNECTION *conn, gss_ctx_id_t *gssctx)
+{
+ conn->gssctx=gssctx;
+}
+
+TRP_CONNECTION_STATUS trp_connection_get_status(TRP_CONNECTION *conn)
+{
+ TRP_CONNECTION_STATUS status;
+ pthread_mutex_lock(&(conn->status_mutex));
+ status=conn->status;
+ pthread_mutex_unlock(&(conn->status_mutex));
+ return status;
+}
+
+void trp_connection_set_status(TRP_CONNECTION *conn, TRP_CONNECTION_STATUS status)
+{
+ pthread_mutex_lock(&(conn->status_mutex));
+ conn->status=status;
+ pthread_mutex_unlock(&(conn->status_mutex));
+}
+
+pthread_t *trp_connection_get_thread(TRP_CONNECTION *conn)
+{
+ return conn->thread;
+}
+
+void trp_connection_set_thread(TRP_CONNECTION *conn, pthread_t *thread)
+{
+ conn->thread=thread;
+}
+
+TRP_CONNECTION *trp_connection_get_next(TRP_CONNECTION *conn)
+{
+ return conn->next;
+}
+
+static void trp_connection_set_next(TRP_CONNECTION *conn, TRP_CONNECTION *next)
+{
+ conn->next=next;
+}
+
+static TRP_CONNECTION *trp_connection_get_tail(TRP_CONNECTION *conn)
+{
+ while((conn!=NULL)&&(trp_connection_get_next(conn)!=NULL))
+ conn=trp_connection_get_next(conn);
+ return conn;
+}
+
+void trp_connection_append(TRP_CONNECTION *conn, TRP_CONNECTION *new)
+{
+ trp_connection_set_next(trp_connection_get_tail(conn), new);
+}
+
+static void trp_connection_mutex_init(TRP_CONNECTION *conn)
+{
+ pthread_mutex_init(&(conn->status_mutex), NULL);
+}
+
+/* talloc destructor for a connection: ensures connection is closed, memory freed */
+static int trp_connection_destructor(void *object)
+{
+ TRP_CONNECTION *conn=talloc_get_type_abort(object, TRP_CONNECTION); /* aborts on wrong type */
+ if ((trp_connection_get_status(conn)!=TRP_CONNECTION_DOWN)
+ && (trp_connection_get_fd(conn)!=-1))
+ close(trp_connection_get_fd(conn));
+ if (conn->gssname!=NULL)
+ tr_free_name(conn->gssname);
+ return 0;
+}
+
+TRP_CONNECTION *trp_connection_new(TALLOC_CTX *mem_ctx)
+{
+ TRP_CONNECTION *new_conn=talloc(mem_ctx, TRP_CONNECTION);
+ gss_ctx_id_t *gssctx=NULL;
+ pthread_t *thread=NULL;
+
+
+ if (new_conn != NULL) {
+ trp_connection_set_next(new_conn, NULL);
+ trp_connection_set_fd(new_conn, -1);
+ trp_connection_set_gssctx(new_conn, NULL);
+ trp_connection_mutex_init(new_conn);
+ trp_connection_set_status(new_conn, TRP_CONNECTION_DOWN);
+ thread=talloc(new_conn, pthread_t);
+ if (thread==NULL) {
+ talloc_free(new_conn);
+ return NULL;
+ }
+ trp_connection_set_thread(new_conn, thread);
+ gssctx=talloc(new_conn, gss_ctx_id_t);
+ if (gssctx==NULL) {
+ talloc_free(new_conn);
+ return NULL;
+ }
+ trp_connection_set_gssctx(new_conn, gssctx);
+ talloc_set_destructor((void *)new_conn, trp_connection_destructor);
+ }
+ return new_conn;
+}
+
+void trp_connection_free(TRP_CONNECTION *conn)
+{
+ /* TODO: shut down connection if it is still open */
+ talloc_free(conn);
+}
+
+
+/* returns 0 on authorization success, 1 on failure, or -1 in case of error */
+int trp_connection_auth(TRP_CONNECTION *conn, TRP_AUTH_FUNC auth_callback, void *callback_data)
+{
+ int rc = 0;
+ int auth, autherr = 0;
+ gss_buffer_desc nameBuffer = {0, NULL};
+ gss_ctx_id_t gssctx;
+
+ /* TODO: shouldn't really peek into TR_NAME... */
+ nameBuffer.length = trp_connection_get_gssname(conn)->len;
+ nameBuffer.value = trp_connection_get_gssname(conn)->buf;
+
+ tr_debug("trp_connection_auth: beginning passive authentication");
+ if (rc = gsscon_passive_authenticate(trp_connection_get_fd(conn), nameBuffer, &gssctx, auth_callback, callback_data)) {
+ tr_debug("trp_connection_auth: Error from gsscon_passive_authenticate(), rc = 0x%08X.", rc);
+ return -1;
+ }
+
+ tr_debug("trp_connection_auth: beginning second stage authentication");
+ if (rc = gsscon_authorize(gssctx, &auth, &autherr)) {
+ tr_debug("trp_connection_auth: Error from gsscon_authorize, rc = %d, autherr = %d.",
+ rc, autherr);
+ return -1;
+ }
+
+ if (auth)
+ tr_debug("trp_connection_auth: Connection authenticated, fd = %d.", trp_connection_get_fd(conn));
+ else
+ tr_debug("trp_connection_auth: Authentication failed, fd = %d.", trp_connection_get_fd(conn));
+
+ return !auth;
+}
+
+/* Accept connection */
+TRP_CONNECTION *trp_connection_accept(TALLOC_CTX *mem_ctx, int listen, TR_NAME *gssname, TRP_AUTH_FUNC auth_handler, TRP_REQ_FUNC req_handler,
+ void *cookie)
+{
+ int conn_fd=-1;
+ TRP_CONNECTION *conn=NULL;
+
+ conn_fd = accept(listen, NULL, NULL);
+
+ if (0 > conn_fd) {
+ tr_notice("trp_connection_accept: accept() returned error.");
+ return NULL;
+ }
+ conn=trp_connection_new(mem_ctx);
+ trp_connection_set_fd(conn, conn_fd);
+ trp_connection_set_gssname(conn, gssname);
+ return conn;
+}
+
#include <tr_trp.h>
-TRPC_INSTANCE *trpc_create (TALLOC_CTX *mem_ctx)
+TRPC_INSTANCE *trpc_new (TALLOC_CTX *mem_ctx)
{
return talloc_zero(mem_ctx, TRPC_INSTANCE);
}
-void trpc_destroy (TRPC_INSTANCE *trpc)
+void trpc_free (TRPC_INSTANCE *trpc)
{
if (trpc)
talloc_free(trpc);
#include <tr_debug.h>
#include <trp_internal.h>
-/* connections and sets of connections */
-TRPS_CONNECTION *trps_connection_new(TALLOC_CTX *mem_ctx)
-{
- TRPS_CONNECTION *new_conn=talloc_new(mem_ctx, TRPS_CONNECTION);
-
- if (new_conn != NULL) {
- new_conn->conn=-1;
- new_conn->gssctx=0;
- }
-
- return new_conn;
-}
-
-
-TRPS_CONNECTION_SET *trps_connection_set_new(TALLOC_CTX *mem_ctx)
+TRPS_INSTANCE *trps_new (TALLOC_CTX *mem_ctx)
{
- TRPS_CONNECTION_SET *new_set=talloc_new(mem_ctx, TRPS_CONNECTION_SET);
- int ii=0;
-
- if (new_set != NULL) {
- new_set->nconn=0;
- for(ii=0; ii<TRPS_CONNECTIONS_MAX; ii++)
- new_set->conn[ii]=0;
- }
-
- return new_set;
-}
-
-TRPS_ERR trps_connection_set_add(TRPS_CONNECTION_SET *tcs, TRPS_CONNECTION *new_conn)
-{
- TR_ERR err=TRPS_ERR_OK;
-
- if (tcs->nconn < TRPS_CONNECTIONS_MAX) {
- tcs->conn[tcs->nconn]=new_conn;
- talloc_steal(tcs, new_conn);
- tcs->nconn++;
- } else {
- err=TRPS_ERR_MAX_CONN;
+ TRPS_INSTANCE *trps=talloc(mem_ctx, TRPS_INSTANCE);
+ if (trps!=NULL) {
+ trps->hostname=NULL;
+ trps->port=0;
+ trps->cookie=NULL;
+ trps->conn=NULL;
+ trps->mq=tr_mq_new(trps);
+ if (trps->mq==NULL) {
+ /* failed to allocate mq */
+ talloc_free(trps);
+ trps=NULL;
+ }
}
-
- return err;
+ return trps;
}
-int trps_connection_set_del(TRPS_CONNECTION_SET *tcs, TRPS_CONNECTION *conn)
+void trps_free (TRPS_INSTANCE *trps)
{
- /* not implemented */
- return TRPS_ERR_UNKNOWN;
+ if (trps!=NULL)
+ talloc_free(trps);
}
-int trps_connection_set_len(TRPS_CONNECTION_SET *tcs)
+/* stand-in for a function that finds the connection for a particular peer */
+#if 0
+static TRP_CONNECTION *trps_find_connection(TRPS_INSTANCE *trps)
{
- return tcs->nconn;
+ return trps->conn;
}
+#endif
-
-
-
-TRPS_INSTANCE *trps_create (TALLOC_CTX *mem_ctx)
+void trps_add_connection(TRPS_INSTANCE *trps, TRP_CONNECTION *new)
{
- return talloc_zero(mem_ctx, TRPS_INSTANCE);
-}
+ if (trps->conn==NULL)
+ trps->conn=new;
+ else
+ trp_connection_append(trps->conn, new);
-void trps_destroy (TRPS_INSTANCE *trps)
-{
- if (trps)
- talloc_free(trps);
+ talloc_steal(trps, new);
}
-
int trps_send_msg (TRPS_INSTANCE *trps,
int conn,
gss_ctx_id_t gssctx,
}
/* returns EACCES if authorization is denied */
-static int trps_auth_cb(gss_name_t clientName, gss_buffer_t displayName,
- void *data)
+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);
+ if (0!=inst->auth_handler(clientName, displayName, inst->cookie)) {
+ tr_debug("trps_auth_cb: client '%.*s' denied authorization.", displayName->length, displayName->value);
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;
-}
-
+#if 0
static int trps_read_message (TRPS_INSTANCE *trps, int conn, gss_ctx_id_t *gssctx, char **msg)
{
int err;
free(buf);
return buflen;
}
+#endif
-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 trps_get_listener(TRPS_INSTANCE *trps,
+ TRP_REQ_FUNC req_handler,
+ TRP_AUTH_FUNC auth_handler,
+ const char *hostname,
+ unsigned int port,
+ void *cookie)
{
int listen = -1;
return listen;
}
-
-/* Accept and process a connection on a port opened with trps_get_listener().
- * Returns the socket FD, or -1 in case of error. */
-int trps_accept(TRPS_INSTANCE *trps, int listen)
-{
- TALLOC_CTX *tmp_ctx=talloc_new(NULL);
- int conn=-1;
- gss_ctx_id_t gssctx;
- TRPS_CONNECTION *trps_conn=0;
- TRPS_ERR trps_err=TRPS_ERR_OK;
-
- conn = accept(listen, NULL, NULL);
-
- if (0 > conn) {
- perror("Error from TRP Server accept()");
- goto cleanup;
- }
-
- /* establish a GSS context */
- if (trps_auth_connection(trps, conn, &gssctx)) {
- tr_notice("trps_accept: Error authorizing TID Server connection.");
- close(conn); /* did not work */
- conn=-1;
- goto cleanup;
- }
-
- tr_notice("trps_accept: Connection authorized!");
-
- /* add this to the list of connections */
- trps_conn=trps_connection_new(tmp_ctx);
- if (trps_conn==NULL) {
- tr_debug("trps_handle_connection: Could not allocate TRPS connection.");
- close(conn);
- conn=-1;
- goto cleanup;
- }
-
- trps_err=trps_connection_set_add(trps->connections, trps_conn); /* handles talloc steal */
- if (trps_err != TRPS_ERR_OK) {
- tr_debug("trps_handle_connection: Error adding connection to set (trps_err=%d)", trps_err);
- close(conn);
- conn=-1;
- goto cleanup;
- }
-
- /* GSS context established, saved to the TRPS instance---success! */
-
-cleanup:
- talloc_free(tmp_ctx);
- return conn;
-}
-
-
-
/* old cruft */
#if 0
static gss_ctx_id_t trps_establish_gss_context (TRPS_INSTANCE *trps, int conn)