From e71ba7e1d0d22436d8f0523de291b8edbc83a180 Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Mon, 13 Jun 2016 16:05:20 -0400 Subject: [PATCH] Separate TRP from main trust router code. Not a functional checkin, probably does not build. --- include/tr_trp.h | 48 +------ include/trp_internal.h | 82 ++++++++++++ tr/tr_trp.c | 261 ++------------------------------------ tr/trpc_main.c | 41 ------ trp/trpc.c | 94 ++++++++++++++ trp/trps.c | 335 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 526 insertions(+), 335 deletions(-) create mode 100644 include/trp_internal.h create mode 100644 trp/trpc.c create mode 100644 trp/trps.c diff --git a/include/tr_trp.h b/include/tr_trp.h index f96f211..1f382ec 100644 --- a/include/tr_trp.h +++ b/include/tr_trp.h @@ -3,54 +3,18 @@ #include +#include #include #include -#include - -#define TRP_PORT 12310 - -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 Client Instance Data */ -typedef struct trpc_instance { - DH *client_dh; /* Client's DH struct with priv and pub keys */ -} TRPC_INSTANCE; - -/* 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 (??) */ -}; +/* 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 */ -TRPC_INSTANCE *trpc_create (TALLOC_CTX *mem_ctx); -void trpc_destroy (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); 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 */ diff --git a/include/trp_internal.h b/include/trp_internal.h new file mode 100644 index 0000000..2557ddc --- /dev/null +++ b/include/trp_internal.h @@ -0,0 +1,82 @@ +#ifndef TRP_INTERNAL_H +#define TRP_INTERNAL_H + +#include + +#include +#include + +#define TRP_PORT 12310 + +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); + + +/* encapsulate a gss context and its connection file handle */ +typedef struct trps_connection { + int conn; + 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 Client Instance Data */ +typedef struct trpc_instance { + DH *client_dh; /* Client's DH struct with priv and pub keys */ +} TRPC_INSTANCE; + +/* 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 (??) */ + TRPS_CONNECTION_SET *connections; /* active GSS connections */ +}; + +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); +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); +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); + +#endif /* TRP_INTERNAL_H */ diff --git a/tr/tr_trp.c b/tr/tr_trp.c index 4d4316b..dbc1d4f 100644 --- a/tr/tr_trp.c +++ b/tr/tr_trp.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -17,186 +18,6 @@ struct tr_trps_event_cookie { TR_CFG_MGR *cfg_mgr; }; -/********** Ersatz TRPC implementation **********/ -TRPC_INSTANCE *trpc_create (TALLOC_CTX *mem_ctx) -{ - return talloc_zero(mem_ctx, TRPC_INSTANCE); -} - -void trpc_destroy (TRPC_INSTANCE *trpc) -{ - if (trpc) - talloc_free(trpc); -} - -/* Connect to a TRP server */ -int trpc_open_connection (TRPC_INSTANCE *trpc, - char *server, - unsigned int port, - gss_ctx_id_t *gssctx) -{ - int err = 0; - int conn = -1; - unsigned int use_port = 0; - - if (0 == port) - use_port = TRP_PORT; - else - use_port = port; - - tr_debug("trpc_open_connection: opening GSS connection to %s:%d", server, use_port); - err = gsscon_connect(server, use_port, "trustrouter", &conn, gssctx); - - if (!err) - return conn; - else - return -1; -} - - -/* simple function, based on tidc_send_req */ -int trpc_send_msg (TRPC_INSTANCE *trpc, - int conn, - gss_ctx_id_t gssctx, - const char *msg_content, - int *resp_handler(), - void *cookie) -{ - char *resp_buf=NULL; - size_t resp_buflen=0; - int err=0; - int rc=0; - - /* Send the request over the connection */ - if (err = gsscon_write_encrypted_token (conn, - gssctx, - msg_content, - strlen(msg_content))) { - tr_err( "trpc_send_msg: Error sending message over connection.\n"); - goto error; - } - - /* Read the response from the connection */ - if (err = gsscon_read_encrypted_token(conn, gssctx, &resp_buf, &resp_buflen)) { - if (resp_buf) - free(resp_buf); - goto error; - } - - tr_debug( "trpc_send_msg: Response Received (%u bytes).\n", (unsigned) resp_buflen); - tr_debug( "%s\n", resp_buf); - - if (resp_handler) - /* Call the caller's response function */ - (*resp_handler)(trpc, resp_buf, cookie); - goto cleanup; - - error: - rc = -1; - cleanup: - if (resp_buf) - free(resp_buf); - return rc; -} - - -/********** 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, @@ -208,10 +29,6 @@ static int tr_trps_req_handler (TRPS_INSTANCE *trps, 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) @@ -241,80 +58,20 @@ static int tr_trps_gss_handler(gss_name_t client_name, TR_NAME *gss_name, } -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; + int conn=-1; - if (0==(event & EV_READ)) + 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); + } else { + conn=trps_accept(trps, listener); + if (conn>0) { + /* need to monitor this fd and trigger events when read becomes possible */ + } + } } diff --git a/tr/trpc_main.c b/tr/trpc_main.c index 088a2d6..75644f4 100644 --- a/tr/trpc_main.c +++ b/tr/trpc_main.c @@ -42,47 +42,6 @@ #include #include -#if 0 -static void tidc_resp_handler (TIDC_INSTANCE * tidc, - TID_REQ *req, - TID_RESP *resp, - void *cookie) -{ - int c_keylen = 0; - unsigned char *c_keybuf = NULL; - int i; - - printf ("Response received! Realm = %s, Community = %s.\n", resp->realm->buf, resp->comm->buf); - - /* Generate the client key -- TBD, handle more than one server */ - if (TID_SUCCESS != resp->result) { - fprintf(stderr, "tidc_resp_handler: Response is an error.\n"); - return; - } - - if (!resp->servers) { - fprintf(stderr, "tidc_resp_handler: Response does not contain server info.\n"); - return; - } - - if (0 > (c_keylen = tr_compute_dh_key(&c_keybuf, - resp->servers->aaa_server_dh->pub_key, - req->tidc_dh))) { - - printf("tidc_resp_handler: Error computing client key.\n"); - return; - } - - /* Print out the client key. */ - printf("Client Key Generated (len = %d):\n", c_keylen); - for (i = 0; i < c_keylen; i++) { - printf("%.2x", c_keybuf[i]); - } - printf("\n"); - - return; -} -#endif /* command-line option setup */ diff --git a/trp/trpc.c b/trp/trpc.c new file mode 100644 index 0000000..7c441d1 --- /dev/null +++ b/trp/trpc.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +TRPC_INSTANCE *trpc_create (TALLOC_CTX *mem_ctx) +{ + return talloc_zero(mem_ctx, TRPC_INSTANCE); +} + +void trpc_destroy (TRPC_INSTANCE *trpc) +{ + if (trpc) + talloc_free(trpc); +} + +/* Connect to a TRP server */ +int trpc_open_connection (TRPC_INSTANCE *trpc, + char *server, + unsigned int port, + gss_ctx_id_t *gssctx) +{ + int err = 0; + int conn = -1; + unsigned int use_port = 0; + + if (0 == port) + use_port = TRP_PORT; + else + use_port = port; + + tr_debug("trpc_open_connection: opening GSS connection to %s:%d", server, use_port); + err = gsscon_connect(server, use_port, "trustrouter", &conn, gssctx); + + if (!err) + return conn; + else + return -1; +} + + +/* simple function, based on tidc_send_req */ +int trpc_send_msg (TRPC_INSTANCE *trpc, + int conn, + gss_ctx_id_t gssctx, + const char *msg_content, + int *resp_handler(), + void *cookie) +{ + char *resp_buf=NULL; + size_t resp_buflen=0; + int err=0; + int rc=0; + + /* Send the request over the connection */ + if (err = gsscon_write_encrypted_token (conn, + gssctx, + msg_content, + strlen(msg_content))) { + tr_err( "trpc_send_msg: Error sending message over connection.\n"); + goto error; + } + + /* Read the response from the connection */ + if (err = gsscon_read_encrypted_token(conn, gssctx, &resp_buf, &resp_buflen)) { + if (resp_buf) + free(resp_buf); + goto error; + } + + tr_debug( "trpc_send_msg: Response Received (%u bytes).\n", (unsigned) resp_buflen); + tr_debug( "%s\n", resp_buf); + + if (resp_handler) + /* Call the caller's response function */ + (*resp_handler)(trpc, resp_buf, cookie); + goto cleanup; + + error: + rc = -1; + cleanup: + if (resp_buf) + free(resp_buf); + return rc; +} diff --git a/trp/trps.c b/trp/trps.c new file mode 100644 index 0000000..001d744 --- /dev/null +++ b/trp/trps.c @@ -0,0 +1,335 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#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_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; + } + + return err; +} + +int trps_connection_set_del(TRPS_CONNECTION_SET *tcs, TRPS_CONNECTION *conn) +{ + /* not implemented */ + return TRPS_ERR_UNKNOWN; +} + +int trps_connection_set_len(TRPS_CONNECTION_SET *tcs) +{ + return tcs->nconn; +} + + + + +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); +} + + +int trps_send_msg (TRPS_INSTANCE *trps, + int conn, + gss_ctx_id_t gssctx, + const char *msg_content) +{ + int err=0; + int rc=0; + + /* Send the request over the connection */ + if (err = gsscon_write_encrypted_token (conn, + gssctx, + msg_content, + strlen(msg_content))) { + tr_err( "trps_send_msg: Error sending message over connection.\n"); + rc = -1; + } + + return rc; +} + +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; +} + +/* 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; +} + +static int trps_read_message (TRPS_INSTANCE *trps, int conn, gss_ctx_id_t *gssctx, char **msg) +{ + int err; + char *buf; + size_t buflen = 0; + + if (err = gsscon_read_encrypted_token(conn, *gssctx, &buf, &buflen)) { + if (buf) + free(buf); + return -1; + } + + tr_debug("trps_read_request(): Request Received, %u bytes.", (unsigned) buflen); + tr_debug("trps_read_request(): %.*s", buflen, buf); + + *msg=talloc_strndup(NULL, buf, buflen); /* no context owns this! */ + free(buf); + return buflen; +} + +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(). + * 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) +{ + TALLOC_CTX *tmp_ctx=talloc_new(NULL); + gss_ctx_id_t gssctx = GSS_C_NO_CONTEXT; + char *msg_rec=NULL; + int msg_len = 0; + int rc=0; + + if (trps_auth_connection(trps, conn, &gssctx)) + tr_notice("trps_establish_gss_context: Error authorizing TID Server connection."); + else: + tr_notice("trps_establish_gss_context: Connection authorized!"); + return gssctx; + + msg_len = trps_read_message(trps, conn, &gssctx, &msg_rec); + talloc_steal(tmp_ctx, msg_rec); /* get this in our context */ + if (0 > msg_len) { + tr_debug("trps_handle_connection: Error from trps_read_message()"); + goto cleanup; + } + + tr_debug("trps_handle_connection: msg_len=%d", msg_len); + reply=talloc_asprintf(tmp_ctx, "TRPS heard: %.*s", msg_len, msg_rec); + if (0 > (rc = trps_send_msg(trps, conn, gssctx, reply))) { + tr_debug("trps_handle_connection: Error from trps_send_message(), rc = %d.", rc); + } + +cleanup: + talloc_free(tmp_ctx); + return conn; +} +#endif -- 2.1.4