From 36204b9350996b2ce762adb0db4146df560190c1 Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Fri, 24 Jun 2016 11:19:59 -0400 Subject: [PATCH] Authenticate GSS context in separate thread. (Not fully working yet.) --- Makefile.am | 71 ++++++++++++----- common/tr_mq.c | 29 +++---- include/tr_mq.h | 6 +- include/tr_trp.h | 7 +- include/trp_internal.h | 133 +++++++++++++------------------ include/trust_router/trp.h | 39 +++++++++ tr/tr_main.c | 35 +++++++- tr/tr_trp.c | 63 ++++++++++++--- tr/trpc_main.c | 4 +- trp/trp_conn.c | 192 ++++++++++++++++++++++++++++++++++++++++++++ trp/trpc.c | 4 +- trp/trps.c | 194 +++++++++------------------------------------ 12 files changed, 481 insertions(+), 296 deletions(-) create mode 100644 trp/trp_conn.c diff --git a/Makefile.am b/Makefile.am index 0581b99..851a127 100644 --- a/Makefile.am +++ b/Makefile.am @@ -12,34 +12,57 @@ common_srcs = common/tr_name.c \ 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 \ @@ -55,15 +78,18 @@ common/tr_rp.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 \ @@ -73,21 +99,28 @@ common_mq_test_mq_test_SOURCES = common/tr_mq.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 \ diff --git a/common/tr_mq.c b/common/tr_mq.c index b2e854c..4e43091 100644 --- a/common/tr_mq.c +++ b/common/tr_mq.c @@ -52,18 +52,6 @@ static void tr_mq_msg_set_next(TR_MQ_MSG *msg, TR_MQ_MSG *next) 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) { @@ -94,7 +82,7 @@ int tr_mq_unlock(TR_MQ *mq) 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; } @@ -104,7 +92,7 @@ static void tr_mq_set_head(TR_MQ *mq, TR_MQ_MSG *msg) 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; } @@ -114,20 +102,27 @@ static void tr_mq_set_tail(TR_MQ *mq, TR_MQ_MSG *msg) 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); diff --git a/include/tr_mq.h b/include/tr_mq.h index cc5d21c..cb8436c 100644 --- a/include/tr_mq.h +++ b/include/tr_mq.h @@ -4,10 +4,6 @@ #include #include -/* REMOVE */ -#define FALSE 0 -#define TRUE 1 - /* msg for inter-thread messaging */ typedef struct tr_mq_msg TR_MQ_MSG; struct tr_mq_msg { @@ -38,7 +34,7 @@ TR_MQ *tr_mq_new(TALLOC_CTX *mem_ctx); 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); diff --git a/include/tr_trp.h b/include/tr_trp.h index 1f382ec..48bc331 100644 --- a/include/tr_trp.h +++ b/include/tr_trp.h @@ -2,17 +2,12 @@ #define TR_TRP_H #include +#include #include #include #include -/* 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); diff --git a/include/trp_internal.h b/include/trp_internal.h index d951012..ca60364 100644 --- a/include/trp_internal.h +++ b/include/trp_internal.h @@ -1,19 +1,15 @@ #ifndef TRP_INTERNAL_H #define TRP_INTERNAL_H +#include #include #include #include +#include #include /* 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; @@ -30,7 +26,6 @@ typedef union trp_inforec_data { /* TRP_INFOREC_COMM *comm; */ } TRP_INFOREC_DATA; -typedef struct trp_inforec TRP_INFOREC; struct trp_inforec { TRP_INFOREC *next; TRP_INFOREC_TYPE type; @@ -46,59 +41,33 @@ struct trp_req { 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; @@ -106,38 +75,50 @@ typedef struct 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 */ diff --git a/include/trust_router/trp.h b/include/trust_router/trp.h index e160543..fd4d5cd 100644 --- a/include/trust_router/trp.h +++ b/include/trust_router/trp.h @@ -17,8 +17,47 @@ typedef enum trp_rc { 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 */ diff --git a/tr/tr_main.c b/tr/tr_main.c index 5b2559f..65a9521 100644 --- a/tr/tr_main.c +++ b/tr/tr_main.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -49,6 +50,8 @@ #include #include +#define TALLOC_DEBUG_ENABLE 1 + /***** command-line option handling / setup *****/ /* Strip trailing / from a path name.*/ @@ -106,9 +109,24 @@ static error_t parse_option(int key, char *arg, struct argp_state *state) 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; @@ -116,6 +134,14 @@ int main (int argc, char *argv[]) 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(); @@ -149,18 +175,19 @@ int main (int argc, char *argv[]) } /***** 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."); diff --git a/tr/tr_trp.c b/tr/tr_trp.c index dbc1d4f..9a416e8 100644 --- a/tr/tr_trp.c +++ b/tr/tr_trp.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -21,7 +22,6 @@ struct tr_trps_event_cookie { static int tr_trps_req_handler (TRPS_INSTANCE *trps, TRP_REQ *orig_req, - TRP_RESP *resp, void *tr_in) { if (orig_req != NULL) @@ -30,13 +30,14 @@ static int tr_trps_req_handler (TRPS_INSTANCE *trps, } -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()"); @@ -46,32 +47,73 @@ static int tr_trps_gss_handler(gss_name_t client_name, TR_NAME *gss_name, } /* 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); } @@ -130,3 +172,4 @@ cleanup: talloc_free(tmp_ctx); return retval; } + diff --git a/tr/trpc_main.c b/tr/trpc_main.c index 75644f4..330b11a 100644 --- a/tr/trpc_main.c +++ b/tr/trpc_main.c @@ -139,7 +139,7 @@ int main (int argc, 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; @@ -160,7 +160,7 @@ int main (int argc, } /* Clean-up the TRP client instance, and exit */ - trpc_destroy(trpc); + trpc_free(trpc); return 0; } diff --git a/trp/trp_conn.c b/trp/trp_conn.c new file mode 100644 index 0000000..c7f3d30 --- /dev/null +++ b/trp/trp_conn.c @@ -0,0 +1,192 @@ +#include +#include +#include +#include + +#include +#include + +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; +} + diff --git a/trp/trpc.c b/trp/trpc.c index 7c441d1..61ac09f 100644 --- a/trp/trpc.c +++ b/trp/trpc.c @@ -12,12 +12,12 @@ #include -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); diff --git a/trp/trps.c b/trp/trps.c index 001d744..d0e6a31 100644 --- a/trp/trps.c +++ b/trp/trps.c @@ -10,76 +10,49 @@ #include #include -/* 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; iiconn[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, @@ -133,56 +106,20 @@ static int trps_listen (TRPS_INSTANCE *trps, int port) } /* 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; @@ -202,13 +139,14 @@ static int trps_read_message (TRPS_INSTANCE *trps, int conn, gss_ctx_id_t *gssct 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; @@ -245,60 +183,6 @@ static int trps_get_listener(TRPS_INSTANCE *trps, 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) -- 2.1.4