Decode JSON TRP messages, then send to main thread.
authorJennifer Richards <jennifer@painless-security.com>
Sat, 25 Jun 2016 01:41:28 +0000 (21:41 -0400)
committerJennifer Richards <jennifer@painless-security.com>
Sat, 25 Jun 2016 01:41:28 +0000 (21:41 -0400)
common/tr_mq.c
common/tr_msg.c
include/tr_mq.h
include/trp_internal.h
tr/tr_trp.c
trp/trp_conn.c
trp/trpc.c
trp/trps.c

index 02b42ee..5240c1a 100644 (file)
@@ -13,11 +13,16 @@ static int tr_mq_msg_destructor(void *object)
   return 0;
 }
 
-TR_MQ_MSG *tr_mq_msg_new(TALLOC_CTX *mem_ctx)
+TR_MQ_MSG *tr_mq_msg_new(TALLOC_CTX *mem_ctx, const char *message)
 {
   TR_MQ_MSG *msg=talloc(mem_ctx, TR_MQ_MSG);
   if (msg!=NULL) {
     msg->next=NULL;
+    msg->message=talloc_strdup(msg, message);
+    if (msg->message==NULL) {
+      talloc_free(msg);
+      return NULL;
+    }
     msg->p=NULL;
     talloc_set_destructor((void *)msg, tr_mq_msg_destructor);
   }
@@ -30,6 +35,11 @@ void tr_mq_msg_free(TR_MQ_MSG *msg)
     talloc_free(msg);
 }
 
+const char *tr_mq_msg_get_message(TR_MQ_MSG *msg)
+{
+  return msg->message;
+}
+
 void *tr_mq_msg_get_payload(TR_MQ_MSG *msg)
 {
   return msg->p;
index 11c3bff..4faff68 100644 (file)
@@ -43,7 +43,6 @@
 
 #include <tr_msg.h>
 #include <trust_router/tr_name.h>
-#include <tid_internal.h>
 #include <trp_internal.h>
 #include <trust_router/tr_constraint.h>
 #include <tr_debug.h>
@@ -983,5 +982,3 @@ void tr_msg_free_decoded(TR_MSG *msg)
     free (msg);
   }
 }
-
-
index cb8436c..a6f472c 100644 (file)
@@ -8,6 +8,7 @@
 typedef struct tr_mq_msg TR_MQ_MSG;
 struct tr_mq_msg {
   TR_MQ_MSG *next;
+  char *message;
   void *p; /* payload */
   void (*p_free)(void *); /* function to free payload */
 };
@@ -24,8 +25,9 @@ struct tr_mq {
   void *notify_cb_arg;
 };
 
-TR_MQ_MSG *tr_mq_msg_new(TALLOC_CTX *mem_ctx);
+TR_MQ_MSG *tr_mq_msg_new(TALLOC_CTX *mem_ctx, const char *msg);
 void tr_mq_msg_free(TR_MQ_MSG *msg);
+const char *tr_mq_msg_get_message(TR_MQ_MSG *msg);
 void *tr_mq_msg_get_payload(TR_MQ_MSG *msg);
 void tr_mq_msg_set_payload(TR_MQ_MSG *msg, void *p, void (*p_free)(void *));
 
index d8ea986..13e2d65 100644 (file)
@@ -7,6 +7,7 @@
 #include <gsscon.h>
 #include <trust_router/tr_dh.h>
 #include <tr_mq.h>
+#include <tr_msg.h>
 #include <trust_router/trp.h>
 
 /* info records */
@@ -44,10 +45,6 @@ struct trp_req {
 
 typedef struct trps_instance TRPS_INSTANCE;
 
-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,
@@ -65,6 +62,11 @@ struct trp_connection {
   pthread_mutex_t status_mutex;
 };
 
+typedef TRP_RC (*TRPS_MSG_FUNC)(TRPS_INSTANCE *, TRP_CONNECTION *, TR_MSG *);
+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;
+
 /* TRP Client Instance Data */
 typedef struct trpc_instance {
   TRP_CONNECTION *conn;
@@ -76,7 +78,7 @@ struct trps_instance {
   char *hostname;
   unsigned int port;
   TRP_AUTH_FUNC auth_handler;
-  TRP_REQ_FUNC req_handler;
+  TRPS_MSG_FUNC msg_handler;
   void *cookie;
   TRP_CONNECTION *conn; /* connections to peers */
   TR_MQ *mq;
@@ -85,6 +87,7 @@ struct trps_instance {
 
 TRP_CONNECTION *trp_connection_new(TALLOC_CTX *mem_ctx);
 void trp_connection_free(TRP_CONNECTION *conn);
+void trp_connection_close(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);
@@ -92,15 +95,13 @@ 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);
+TRP_CONNECTION *trp_connection_remove(TRP_CONNECTION *conn, TRP_CONNECTION *remove);
 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);
+TRP_CONNECTION *trp_connection_accept(TALLOC_CTX *mem_ctx, int listen, TR_NAME *gssname);
 
 TRPC_INSTANCE *trpc_new (TALLOC_CTX *mem_ctx);
 void trpc_free (TRPC_INSTANCE *trpc);
@@ -113,8 +114,9 @@ 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);
+void trps_remove_connection(TRPS_INSTANCE *trps, TRP_CONNECTION *remove);
 int trps_get_listener(TRPS_INSTANCE *trps,
-                      TRP_REQ_FUNC req_handler,
+                      TRPS_MSG_FUNC msg_handler,
                       TRP_AUTH_FUNC auth_handler,
                       const char *hostname,
                       unsigned int port,
@@ -122,4 +124,5 @@ int trps_get_listener(TRPS_INSTANCE *trps,
 int trps_auth_cb(gss_name_t clientName, gss_buffer_t displayName, void *data);
 TR_MQ_MSG *trps_mq_pop(TRPS_INSTANCE *trps);
 void trps_mq_append(TRPS_INSTANCE *trps, TR_MQ_MSG *msg);
+void trps_handle_connection(TRPS_INSTANCE *trps, TRP_CONNECTION *conn);
 #endif /* TRP_INTERNAL_H */
index e109301..6875e4c 100644 (file)
@@ -4,14 +4,16 @@
 #include <talloc.h>
 #include <errno.h>
 #include <unistd.h>
+#include <string.h>
 
 #include <gsscon.h>
 #include <tr_rp.h>
 #include <trp_internal.h>
 #include <tr_config.h>
 #include <tr_event.h>
-#include <tr_debug.h>
+#include <tr_msg.h>
 #include <tr_trp.h>
+#include <tr_debug.h>
 
 /* hold a trps instance and a config manager */
 struct tr_trps_event_cookie {
@@ -27,13 +29,29 @@ static void tr_trps_mq_cb(TR_MQ *mq, void *arg)
   event_active(mq_ev, 0, 0);
 }
 
-static int tr_trps_req_handler (TRPS_INSTANCE *trps,
-                                TRP_REQ *orig_req, 
-                                void *tr_in)
+static void msg_free_helper(void *p)
 {
-  if (orig_req != NULL) 
-    free(orig_req);
-  return -1; /* not handling anything right now */
+  tr_msg_free_decoded((TR_MSG *)p);
+}
+/* takes a TR_MSG and puts it in a TR_MQ_MSG for processing by the main thread */
+static TRP_RC tr_trps_msg_handler(TRPS_INSTANCE *trps,
+                                  TRP_CONNECTION *conn,
+                                  TR_MSG *tr_msg)
+{
+  TALLOC_CTX *tmp_ctx=talloc_new(NULL);
+  TR_MQ_MSG *mq_msg=NULL;
+
+  /* n.b., conn is available here, but do not hold onto the reference
+   * because it may be cleaned up if the originating connection goes
+   * down before the message is processed */
+  mq_msg=tr_mq_msg_new(tmp_ctx, "tr_msg");
+  if (mq_msg==NULL) {
+    return TRP_NOMEM;
+  }
+  tr_mq_msg_set_payload(mq_msg, (void *)tr_msg, msg_free_helper);
+  trps_mq_append(trps, mq_msg);
+  talloc_free(tmp_ctx); /* cleans up the message if it did not get appended correctly */
+  return TRP_SUCCESS;
 }
 
 
@@ -80,14 +98,10 @@ static void *tr_trps_conn_thread(void *arg)
   TR_MQ_MSG *msg=NULL;
 
   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");
-  
-  msg=tr_mq_msg_new(tmp_ctx);
+  trps_handle_connection(trps, conn);
+
+  msg=tr_mq_msg_new(tmp_ctx, "thread_exit");
+  tr_mq_msg_set_payload(msg, (void *)conn, NULL); /* do not pass a free routine */
   if (msg==NULL)
     tr_err("tr_trps_conn_thread: error allocating TR_MQ_MSG");
   else
@@ -115,7 +129,7 @@ static void tr_trps_event_cb(int listener, short event, void *arg)
     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);
+    conn=trp_connection_accept(tmp_ctx, listener, gssname);
     if (conn!=NULL) {
       /* need to monitor this fd and trigger events when read becomes possible */
       thread_data=talloc(conn, struct thread_data);
@@ -134,21 +148,51 @@ static void tr_trps_event_cb(int listener, short event, void *arg)
   talloc_free(tmp_ctx);
 }
 
+static void tr_trps_cleanup_thread(TRPS_INSTANCE *trps, TRP_CONNECTION *conn)
+{
+  /* everything belonging to the thread is in the TRP_CONNECTION
+   * associated with it */
+  trps_remove_connection(trps, conn);
+  tr_debug("Deleted connection");
+}
+
 static void tr_trps_process_mq(int socket, short event, void *arg)
 {
   TRPS_INSTANCE *trps=talloc_get_type_abort(arg, TRPS_INSTANCE);
   TR_MQ_MSG *msg=NULL;
+  const char *s=NULL;
+  char *tmp=NULL;
 
   tr_debug("tr_trps_process_mw: starting");
   msg=trps_mq_pop(trps);
   while (msg!=NULL) {
-    tr_debug("tr_trps_process_mq: received message");
+    s=tr_mq_msg_get_message(msg);
+    if (0==strcmp(s, "thread_exit")) {
+      tr_trps_cleanup_thread(trps,
+                             talloc_get_type_abort(tr_mq_msg_get_payload(msg),
+                                                   TRP_CONNECTION));
+    }
+    else if (0==strcmp(s, "tr_msg")) {
+      tmp=tr_msg_encode(tr_mq_msg_get_payload(msg));
+      tr_debug("tr_msg: %s", tmp);
+      tr_msg_free_encoded(tmp);
+    }
+    else
+      tr_notice("tr_trps_process_mq: unknown message '%s' received.", tr_mq_msg_get_message(msg));
+
     tr_mq_msg_free(msg);
     msg=trps_mq_pop(trps);
   }
   tr_debug("tr_trps_process_mw: ending");
 }
 
+static int tr_trps_events_destructor(void *obj)
+{
+  TR_TRPS_EVENTS *ev=talloc_get_type_abort(obj, TR_TRPS_EVENTS);
+  if (ev->mq_ev!=NULL)
+    event_free(ev->mq_ev);
+  return 0;
+}
 TR_TRPS_EVENTS *tr_trps_events_new(TALLOC_CTX *mem_ctx)
 {
   TR_TRPS_EVENTS *ev=talloc(mem_ctx, TR_TRPS_EVENTS);
@@ -159,6 +203,7 @@ TR_TRPS_EVENTS *tr_trps_events_new(TALLOC_CTX *mem_ctx)
       talloc_free(ev);
       ev=NULL;
     }
+    talloc_set_destructor((void *)ev, tr_trps_events_destructor);
   }
   return ev;
 }
@@ -199,11 +244,11 @@ int tr_trps_event_init(struct event_base *base,
 
   /* get a trps listener */
   listen_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);
+                                       tr_trps_msg_handler,
+                                       tr_trps_gss_handler,
+                                       cfg_mgr->active->internal->hostname,
+                                       cfg_mgr->active->internal->trps_port,
+                                       (void *)cookie);
   if (listen_ev->sock_fd < 0) {
     tr_crit("Error opening TRP server socket.");
     retval=1;
index c7f3d30..1065116 100644 (file)
@@ -45,7 +45,7 @@ TRP_CONNECTION_STATUS trp_connection_get_status(TRP_CONNECTION *conn)
   return status;
 }
 
-void trp_connection_set_status(TRP_CONNECTION *conn, TRP_CONNECTION_STATUS status)
+static void trp_connection_set_status(TRP_CONNECTION *conn, TRP_CONNECTION_STATUS status)
 {
   pthread_mutex_lock(&(conn->status_mutex));
   conn->status=status;
@@ -72,6 +72,37 @@ static void trp_connection_set_next(TRP_CONNECTION *conn, TRP_CONNECTION *next)
   conn->next=next;
 }
 
+/* Ok to call more than once; guarantees connection no longer in the list.
+ * Returns handle to new list, you must replace your old handle on the list with this.  */
+TRP_CONNECTION *trp_connection_remove(TRP_CONNECTION *conn, TRP_CONNECTION *remove)
+{
+  TRP_CONNECTION *cur=conn;
+  TRP_CONNECTION *last=NULL;
+
+  if (cur==NULL)
+    return NULL;
+
+  /* first element is a special case */
+  if (cur==remove) {
+    conn=trp_connection_get_next(cur); /* advance list head */
+    trp_connection_free(cur);
+  } else {
+    /* it was not the first element */
+    last=cur;
+    cur=trp_connection_get_next(cur);
+    while (cur!=NULL) {
+      if (cur==remove) {
+        trp_connection_set_next(last, trp_connection_get_next(cur));
+        trp_connection_free(cur);
+        break;
+      }
+      last=cur;
+      cur=trp_connection_get_next(cur);
+    }
+  }
+  return conn;
+}
+
 static TRP_CONNECTION *trp_connection_get_tail(TRP_CONNECTION *conn)
 {
   while((conn!=NULL)&&(trp_connection_get_next(conn)!=NULL))
@@ -115,17 +146,17 @@ TRP_CONNECTION *trp_connection_new(TALLOC_CTX *mem_ctx)
     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);
+    if (thread==NULL) {
+      talloc_free(new_conn);
+      return NULL;
+    }
+    trp_connection_set_thread(new_conn, thread);
     talloc_set_destructor((void *)new_conn, trp_connection_destructor);
   }
   return new_conn;
@@ -133,10 +164,15 @@ TRP_CONNECTION *trp_connection_new(TALLOC_CTX *mem_ctx)
 
 void trp_connection_free(TRP_CONNECTION *conn)
 {
-  /* TODO: shut down connection if it is still open */
   talloc_free(conn);
 }
 
+void trp_connection_close(TRP_CONNECTION *conn)
+{
+  close(trp_connection_get_fd(conn));
+  trp_connection_set_fd(conn, -1);
+  trp_connection_set_status(conn, TRP_CONNECTION_DOWN);
+}
 
 /* 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)
@@ -144,20 +180,22 @@ int trp_connection_auth(TRP_CONNECTION *conn, TRP_AUTH_FUNC auth_callback, void
   int rc = 0;
   int auth, autherr = 0;
   gss_buffer_desc nameBuffer = {0, NULL};
-  gss_ctx_id_t gssctx;
+  gss_ctx_id_t *gssctx=trp_connection_get_gssctx(conn);
 
   /* 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)) {
+  rc = gsscon_passive_authenticate(trp_connection_get_fd(conn), nameBuffer, gssctx, auth_callback, callback_data);
+  gss_release_buffer(NULL, &nameBuffer);
+  if (rc!=0) {
     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)) {
+  if (rc = gsscon_authorize(*gssctx, &auth, &autherr)) {
     tr_debug("trp_connection_auth: Error from gsscon_authorize, rc = %d, autherr = %d.", 
              rc, autherr);
     return -1;
@@ -172,8 +210,7 @@ int trp_connection_auth(TRP_CONNECTION *conn, TRP_AUTH_FUNC auth_callback, void
 }
 
 /* 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)
+TRP_CONNECTION *trp_connection_accept(TALLOC_CTX *mem_ctx, int listen, TR_NAME *gssname)
 {
   int conn_fd=-1;
   TRP_CONNECTION *conn=NULL;
@@ -187,6 +224,7 @@ TRP_CONNECTION *trp_connection_accept(TALLOC_CTX *mem_ctx, int listen, TR_NAME *
   conn=trp_connection_new(mem_ctx);
   trp_connection_set_fd(conn, conn_fd);
   trp_connection_set_gssname(conn, gssname);
+  trp_connection_set_status(conn, TRP_CONNECTION_UP);
   return conn;
 }
 
index 61ac09f..aab9e21 100644 (file)
@@ -70,19 +70,6 @@ int trpc_send_msg (TRPC_INSTANCE *trpc,
     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:
index 34d6533..2576f0e 100644 (file)
@@ -63,6 +63,12 @@ void trps_add_connection(TRPS_INSTANCE *trps, TRP_CONNECTION *new)
   talloc_steal(trps, new);
 }
 
+/* ok to call more than once; guarantees connection no longer in the list */
+void trps_remove_connection(TRPS_INSTANCE *trps, TRP_CONNECTION *remove)
+{
+  trps->conn=trp_connection_remove(trps->conn, remove);
+}
+
 int trps_send_msg (TRPS_INSTANCE *trps,
                    int conn,
                    gss_ctx_id_t gssctx,
@@ -129,30 +135,33 @@ int trps_auth_cb(gss_name_t clientName, gss_buffer_t displayName, void *data)
   return result;
 }
 
-#if 0
-static int trps_read_message (TRPS_INSTANCE *trps, int conn, gss_ctx_id_t *gssctx, char **msg)
+static TRP_RC trps_read_message(TRPS_INSTANCE *trps, TRP_CONNECTION *conn, TR_MSG **msg)
 {
   int err;
   char *buf;
   size_t buflen = 0;
 
-  if (err = gsscon_read_encrypted_token(conn, *gssctx, &buf, &buflen)) {
+  tr_debug("trps_read_message: started");
+  if (err = gsscon_read_encrypted_token(trp_connection_get_fd(conn),
+                                       *(trp_connection_get_gssctx(conn)), 
+                                        &buf,
+                                        &buflen)) {
+    tr_debug("trps_read_message: error");
     if (buf)
       free(buf);
-    return -1;
+    return TRP_ERROR;
   }
 
-  tr_debug("trps_read_request(): Request Received, %u bytes.", (unsigned) buflen);
-  tr_debug("trps_read_request(): %.*s", buflen, buf);
+  tr_debug("trps_read_message(): Request Received, %u bytes.", (unsigned) buflen);
+  tr_debug("trps_read_message(): %.*s", buflen, buf);
 
-  *msg=talloc_strndup(NULL, buf, buflen); /* no context owns this! */
+  *msg=tr_msg_decode(buf, buflen);
   free(buf);
-  return buflen;
+  return TRP_SUCCESS;
 }
-#endif
 
 int trps_get_listener(TRPS_INSTANCE *trps,
-                      TRP_REQ_FUNC req_handler,
+                      TRPS_MSG_FUNC msg_handler,
                       TRP_AUTH_FUNC auth_handler,
                       const char *hostname,
                       unsigned int port,
@@ -183,7 +192,7 @@ int trps_get_listener(TRPS_INSTANCE *trps,
 
   if (listen > 0) {
     /* store the caller's request handler & cookie */
-    trps->req_handler = req_handler;
+    trps->msg_handler = msg_handler;
     trps->auth_handler = auth_handler;
     trps->hostname = talloc_strdup(trps, hostname);
     trps->port = port;
@@ -193,37 +202,36 @@ int trps_get_listener(TRPS_INSTANCE *trps,
   return listen;
 }
 
-/* old cruft */
-#if 0
-static gss_ctx_id_t trps_establish_gss_context (TRPS_INSTANCE *trps, int conn)
+void trps_handle_connection(TRPS_INSTANCE *trps, TRP_CONNECTION *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;
+  TR_MSG *msg=NULL;
+  TRP_RC rc=TRP_ERROR;
 
-  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;
+  /* 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("trps_handle_connection: authorized connection");
   
-  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);
+  /* loop as long as the connection exists */
+  while (trp_connection_get_status(conn)==TRP_CONNECTION_UP) {
+    rc=trps_read_message(trps, conn, &msg);
+    switch(rc) {
+    case TRP_SUCCESS:
+      trps->msg_handler(trps, conn, msg); /* send the TR_MSG off to the callback */
+      break;
+
+    case TRP_ERROR:
+      trp_connection_close(conn);
+      break;
+
+    default:
+      tr_debug("trps_handle_connection: trps_read_message failed (%d)", rc);
+    }
   }
 
-cleanup:
+  tr_debug("trps_handle_connection: connection closed.");
   talloc_free(tmp_ctx);
-  return conn;
 }
-#endif