Initial TIDR client and server code
authorMargaret Wasserman <mrw@debian.(none)>
Mon, 17 Dec 2012 22:12:35 +0000 (17:12 -0500)
committerMargaret Wasserman <mrw@debian.(none)>
Mon, 17 Dec 2012 22:12:35 +0000 (17:12 -0500)
Makefile.am
include/tidr.h
tidr/example/tidrc_main.c [new file with mode: 0644]
tidr/example/tidrs_main.c [new file with mode: 0644]
tidr/tidrc.c [new file with mode: 0644]
tidr/tidrs.c [new file with mode: 0644]

index 26231dd..2fc0c8f 100644 (file)
@@ -1,4 +1,4 @@
-bin_PROGRAMS= tr/tr tpq/example/tpqc tpq/example/tpqs
+bin_PROGRAMS= tr/tr tpq/example/tpqc tpq/example/tpqs tidr/example/tidrc tidr/example/tidrs
 AM_CPPFLAGS=-I$(srcdir)/include
 SUBDIRS = gsscon 
 
@@ -24,4 +24,18 @@ common/tr_msg.c
 
 tpq_example_tpqs_LDADD = gsscon/libgsscon.la
 
+tidr_example_tidrc_SOURCES = tidr/example/tidrc_main.c \
+tidr/tidrc.c \
+common/tr_name.c \
+common/tr_msg.c
+
+tidr_example_tidrc_LDADD = gsscon/libgsscon.la
+
+tidr_example_tidrs_SOURCES = tidr/example/tidrs_main.c \
+tidr/tidrs.c \
+common/tr_name.c \
+common/tr_msg.c
+
+tidr_example_tidrs_LDADD = gsscon/libgsscon.la
+
 
index 88fcfda..623727b 100644 (file)
 #ifndef TIDR_H
 #define TIDR_H
 
-#define TEMP_ID_REQ_PORT       12310
+#include <gsscon.h>
+#include <tr_name.h>
+
+#define TIDR_PORT      12310
+
+typedef struct tidr_req {
+  struct tidr_req *next_req;
+  int conn;
+  TR_NAME *realm;
+  TR_NAME *coi;
+  void *resp_func;
+  void *cookie;
+} TIDR_REQ;
+
+typedef struct tidr_resp {
+  TR_NAME *realm;
+  TR_NAME *coi;
+  /* Address of AAA Server */
+  /* Credentials */
+  /* Trust Path Used */
+} TIDR_RESP;
+
+typedef struct tidrc_instance {
+  TIDR_REQ *req_list;
+} TIDRC_INSTANCE;
+
+typedef struct tidrs_instance {
+  int req_count;
+  void *req_handler;
+  void *cookie;
+} TIDRS_INSTANCE;
+
+typedef void (TIDRC_RESP_FUNC)(TIDRC_INSTANCE *, TIDR_RESP *, void *);
+typedef int (TIDRS_REQ_FUNC)(TIDRS_INSTANCE *, TIDR_REQ *, TIDR_RESP *, void *);
+
+TIDRC_INSTANCE *tidrc_create (void);
+int tidrc_open_connection (TIDRC_INSTANCE *tidrc, char *server, gss_ctx_id_t *gssctx);
+int tidrc_send_request (TIDRC_INSTANCE *tidrc, int conn, gss_ctx_id_t gssctx, char *realm, char *coi, TIDRC_RESP_FUNC *resp_handler, void *cookie);
+void tidrc_destroy (TIDRC_INSTANCE *tpqc);
+
+TIDRS_INSTANCE *tidrs_create ();
+int tidrs_start (TIDRS_INSTANCE *tidrs, TIDRS_REQ_FUNC *req_handler, void *cookie);
+void tidrs_destroy (TIDRS_INSTANCE *tidrs);
 
 #endif
diff --git a/tidr/example/tidrc_main.c b/tidr/example/tidrc_main.c
new file mode 100644 (file)
index 0000000..16d1512
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2012, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <gsscon.h>
+#include <tidr.h>
+
+static int tidrc_response_received = 0;
+
+void tidrc_print_usage (const char *name)
+{
+  printf("Usage: %s <server> <realm> <coi>\n", name);
+}
+
+void tidrc_resp_handler (TIDRC_INSTANCE * tidrc, 
+                       TIDR_RESP *resp, 
+                       void *cookie) 
+{
+  //  printf ("Response received! Realm = %s, COI = %s.\n", resp->realm->buf, 
+  //     resp->coi->buf);
+  printf ("Response received at handler!\n");
+  tidrc_response_received = 1;
+  return;
+}
+
+int main (int argc, 
+         const char *argv[]) 
+{
+  TIDRC_INSTANCE *tidrc;
+  TIDR_REQ *treq;
+  char *server = NULL;
+  char *realm = NULL;
+  char *coi = NULL;
+  void *cookie = NULL;
+  int conn = 0;
+  int rc;
+  gss_ctx_id_t gssctx;
+
+  /* Parse command-line arguments */ 
+  if (argc != 4) {
+    tidrc_print_usage(argv[0]);
+    exit(1);
+  }
+
+  /* TBD -- validity checking, dealing with quotes, etc. */
+  server = (char *)argv[1];
+  realm = (char *)argv[2];
+  coi = (char *)argv[3];
+
+  /* Create a TIDR client instance */
+  tidrc = tidrc_create();
+
+  /* Set-up TIDR connection */
+  if (-1 == (conn = tidrc_open_connection(tidrc, server, &gssctx))) {
+    /* Handle error */
+    printf("Error in tidrc_open_connection.\n");
+    return 1;
+  };
+
+  /* Send a TIDR request */
+  if (0 > (rc = tidrc_send_request(tidrc, conn, gssctx, realm, coi, 
+                                 &tidrc_resp_handler, NULL))) {
+    /* Handle error */
+    printf("Error in tidrc_send_request, rc = %d.\n", rc);
+    return 1;
+  }
+    
+  /* Wait for a response */
+  while (!tidrc_response_received);
+
+  /* Clean-up the TIDR client instance, and exit */
+  tidrc_destroy(tidrc);
+
+  return 0;
+}
+
diff --git a/tidr/example/tidrs_main.c b/tidr/example/tidrs_main.c
new file mode 100644 (file)
index 0000000..3e2f73c
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2012, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+
+#include <tidr.h>
+
+int tidrs_req_handler (TIDRS_INSTANCE * tidrs,
+                     TIDR_REQ *req, 
+                     TIDR_RESP *resp,
+                     void *cookie)
+{
+  printf("Request received! Realm = %s, COI = %s\n", req->realm->buf, req->coi->buf);
+  if (tidrs)
+    tidrs->req_count++;
+
+  if ((NULL == (resp->realm = tr_dup_name(req->realm))) ||
+      (NULL == (resp->coi = tr_dup_name(req->coi)))) {
+    printf ("Error in tidr_dup_name, not responding.\n");
+    return 1;
+  }
+
+  return 0;
+}
+
+
+int main (int argc, 
+         const char *argv[]) 
+{
+  static TIDRS_INSTANCE *tidrs;
+  int rc = 0;
+
+  /* Parse command-line arguments */ 
+  if (argc != 1)
+    printf("Unexpected arguments, ignored.\n");
+
+  /* Create a TIDR server instance */
+  if (NULL == (tidrs = tidrs_create())) {
+    printf("Error in tidrs_create().  Exiting.\n");
+    return 1;
+  }
+
+  /* Start-up the server, won't return unless there is an error. */
+  rc = tidrs_start(tidrs, &tidrs_req_handler , NULL);
+  
+  printf("Error in tidrs_start(), rc = %d. Exiting.\n");
+
+  /* Clean-up the TIDR server instance */
+  tidrs_destroy(tidrs);
+
+  return 1;
+}
+
diff --git a/tidr/tidrc.c b/tidr/tidrc.c
new file mode 100644 (file)
index 0000000..3a06b00
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2012, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdlib.h>
+#include <jansson.h>
+
+#include <gsscon.h>
+#include <tidr.h>
+
+TIDRC_INSTANCE *tidrc_create ()
+{
+  TIDRC_INSTANCE *tidrc = NULL;
+
+  if (tidrc = malloc(sizeof(TIDRC_INSTANCE)))
+    memset(tidrc, 0, sizeof(TIDRC_INSTANCE));
+
+  return tidrc;
+}
+
+int tidrc_open_connection (TIDRC_INSTANCE *tidrc, 
+                         char *server,
+                         gss_ctx_id_t *gssctx)
+{
+  int err = 0;
+  int conn = -1;
+
+  err = gsscon_connect(server, TIDR_PORT, &conn);
+
+  if (!err)
+    err = gsscon_active_authenticate(conn, NULL, "tempidrequest", gssctx);
+
+  if (!err)
+    return conn;
+  else
+    return -1;
+}
+
+int tidrc_send_request (TIDRC_INSTANCE *tidrc, 
+                      int conn, 
+                      gss_ctx_id_t gssctx,
+                      char *realm, 
+                      char *coi,
+                      TIDRC_RESP_FUNC *resp_handler,
+                      void *cookie)
+
+{
+  json_t *jreq;
+  int err;
+  char *req_buf;
+  char *resp_buf;
+  size_t resp_buflen = 0;
+
+  /* Create a json TIDR request */
+  if (NULL == (jreq = json_object())) {
+    fprintf(stderr,"Error creating json object.\n");
+    return -1;
+  }
+
+  if (0 > (err = json_object_set_new(jreq, "type", json_string("tidr_request")))) {
+    fprintf(stderr, "Error adding type to request.\n");
+    return -1;
+  }
+
+  /* Insert realm and coi into the json request */
+  if (0 > (err = json_object_set_new(jreq, "realm", json_string(realm)))) {
+    fprintf(stderr, "Error adding realm to request.\n");
+    return -1;
+  }
+  if (0 > (err = json_object_set_new(jreq, "coi", json_string(coi)))) {
+    fprintf(stderr, "Error adding coi to request.\n");
+    return -1;
+  }
+
+  /* Generate half of a D-H exchange -- TBD */
+  /* Insert D-H information into the request -- TBD */
+
+  /* Encode the json request */
+  if (NULL == (req_buf = json_dumps(jreq, 0))) {
+    fprintf(stderr, "Error encoding json request.\n");
+    return -1;
+  }
+  
+  printf("Encoded request:\n%s\n", req_buf);
+  
+  /* Send the request over the connection */
+  if (err = gsscon_write_encrypted_token (conn, gssctx, req_buf, 
+                                         strlen(req_buf) + 1)) {
+    fprintf(stderr, "Error sending request over connection.\n");
+    return -1;
+  }
+
+  free(req_buf);
+
+  /* read the response from the connection */
+
+  if (err = gsscon_read_encrypted_token(conn, gssctx, &resp_buf, &resp_buflen)) {
+    if (resp_buf)
+      free(resp_buf);
+    return -1;
+  }
+
+  fprintf(stdout, "Response Received, %d bytes.\n", resp_buflen);
+
+  /* Parse response -- TBD */
+
+  /* Call the caller's response function */
+  (*resp_handler)(tidrc, NULL, cookie);
+
+  if (resp_buf)
+    free(resp_buf);
+
+  return 0;
+}
+
+void tidrc_destroy (TIDRC_INSTANCE *tidrc)
+{
+  if (tidrc)
+    free(tidrc);
+}
+
+
+
+
diff --git a/tidr/tidrs.c b/tidr/tidrs.c
new file mode 100644 (file)
index 0000000..a92b843
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2012, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <jansson.h>
+
+#include <gsscon.h>
+#include <tidr.h>
+
+static int tidrs_listen (int port) 
+{
+    int rc = 0;
+    int conn = -1;
+    struct sockaddr_storage addr;
+    struct sockaddr_in *saddr = (struct sockaddr_in *) &addr;
+    
+    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;
+        
+    if (0 > (rc = bind (conn, (struct sockaddr *) saddr, sizeof(struct sockaddr_in))))
+      return rc;
+        
+    if (0 > (rc = listen(conn, 512)))
+      return rc;
+    
+    fprintf (stdout, "TIDR Server listening on port %d\n", port);
+    return conn; 
+}
+
+static int tidrs_auth_connection (int conn, gss_ctx_id_t *gssctx)
+{
+  int rc = 0;
+  int auth, autherr = 0;
+
+  if (rc = gsscon_passive_authenticate(conn, gssctx)) {
+    fprintf(stderr, "Error from gsscon_passive_authenticate(), rc = %d.\n", rc);
+    return -1;
+  }
+
+  if (rc = gsscon_authorize(*gssctx, &auth, &autherr)) {
+    fprintf(stderr, "Error from gsscon_authorize, rc = %d, autherr = %d.\n", 
+           rc, autherr);
+    return -1;
+  }
+
+  if (auth)
+    fprintf(stdout, "Connection authenticated, conn = %d.\n", conn);
+  else
+    fprintf(stderr, "Authentication failed, conn %d.\n", conn);
+
+  return auth;
+}
+
+static int tidrs_read_request (int conn, gss_ctx_id_t *gssctx, TIDR_REQ *req)
+{
+  int err;
+  char *buf;
+  size_t buflen = 0;
+
+  if (err = gsscon_read_encrypted_token(conn, *gssctx, &buf, &buflen)) {
+    if (buf)
+      free(buf);
+    return -1;
+  }
+
+  fprintf(stdout, "Request Received, %d bytes.\n", buflen);
+
+  /* Parse request -- TBD */
+
+  if (buf)
+    free(buf);
+
+  return buflen;
+}
+
+static int tidrs_handle_request (TIDR_REQ *req, TIDR_RESP *resp) 
+{
+  return 0;
+}
+
+static int tidrs_send_response (int conn, gss_ctx_id_t *gssctx, TIDR_RESP *resp)
+{
+  json_t *jreq;
+  int err;
+  char *resp_buf;
+
+  /* Create a json TIDR response */
+  if (NULL == (jreq = json_object())) {
+    fprintf(stderr,"Error creating json object.\n");
+    return -1;
+  }
+
+  if (0 > (err = json_object_set_new(jreq, "type", json_string("tidr_response")))) {
+    fprintf(stderr, "Error adding type to response.\n");
+    return -1;
+  }
+  if (0 > (err = json_object_set_new(jreq, "result", json_string("success")))) {
+    fprintf(stderr, "Error adding result to response.\n");
+    return -1;
+  }
+  if (0 > (err = json_object_set_new(jreq, "msg", json_string("Temporary ID configured")))) {
+    fprintf(stderr, "Error adding msg to response.\n");
+    return -1;
+  }
+
+  /* Encode the json response */
+  if (NULL == (resp_buf = json_dumps(jreq, 0))) {
+    fprintf(stderr, "Error encoding json response.\n");
+    return -1;
+  }
+  
+  printf("Encoded response:\n%s\n", resp_buf);
+  
+  /* Send the request over the connection */
+  if (err = gsscon_write_encrypted_token (conn, *gssctx, resp_buf, 
+                                         strlen(resp_buf) + 1)) {
+    fprintf(stderr, "Error sending request over connection.\n");
+    return -1;
+  }
+
+  free(resp_buf);
+
+  return 0;
+
+}
+
+static void tidrs_handle_connection (int conn)
+{
+  TIDR_REQ req;
+  TIDR_RESP resp;
+  int rc;
+  gss_ctx_id_t gssctx = GSS_C_NO_CONTEXT;
+
+  if (!tidrs_auth_connection(conn, &gssctx)) {
+    fprintf(stderr, "Error authorizing TIDR Server connection, rc = %d.\n", rc);
+    close(conn);
+    return;
+  }
+
+  printf("Connection authorized!\n");
+
+  while (1) {  /* continue until an error breaks us out */
+
+    if (0 > (rc = tidrs_read_request(conn, &gssctx, &req))) {
+      fprintf(stderr, "Error from tidrs_read_request(), rc = %d.\n", rc);
+      return;
+    } else if (0 == rc) {
+      continue;
+    }
+
+    if (0 > (rc = tidrs_handle_request(&req, &resp))) {
+      fprintf(stderr, "Error from tidrs_handle_request(), rc = %d.\n", rc);
+      return;
+    }
+
+    if (0 > (rc = tidrs_send_response(conn, &gssctx, &resp))) {
+      fprintf(stderr, "Error from tidrs_send_response(), rc = %d.\n", rc);
+      return;
+    }
+  }  
+
+  return;
+}
+
+TIDRS_INSTANCE *tidrs_create ()
+{
+  TIDRS_INSTANCE *tidrs = 0;
+  if (tidrs = malloc(sizeof(TIDRS_INSTANCE)))
+    memset(tidrs, 0, sizeof(TIDRS_INSTANCE));
+  return tidrs;
+}
+
+int tidrs_start (TIDRS_INSTANCE *tidrs, 
+               TIDRS_REQ_FUNC *req_handler,
+               void *cookie)
+{
+  int listen = -1;
+  int conn = -1;
+  pid_t pid;
+
+  if (0 > (listen = tidrs_listen(TIDR_PORT)))
+    perror ("Error from tidrs_listen()");
+
+  while(1) {   /* accept incoming conns until we are stopped */
+
+    if (0 > (conn = accept(listen, NULL, NULL))) {
+      perror("Error from TIDRS Server accept()");
+      return 1;
+    }
+
+    if (0 > (pid = fork())) {
+      perror("Error on fork()");
+      return 1;
+    }
+
+    if (pid == 0) {
+      close(listen);
+      tidrs_handle_connection(conn);
+      close(conn);
+      exit(0);
+    } else {
+      close(conn);
+    }
+  }
+
+  return 1;    /* should never get here */
+}
+
+void tidrs_destroy (TIDRS_INSTANCE *tidrs)
+{
+  free(tidrs);
+}
+
+