TR request and response message handlers.
authorMargaret Wasserman <margaret@moonshot-proxy.home>
Wed, 3 Apr 2013 20:58:49 +0000 (16:58 -0400)
committerMargaret Wasserman <margaret@moonshot-proxy.home>
Wed, 3 Apr 2013 20:58:49 +0000 (16:58 -0400)
README
include/tr.h
include/tr_idp.h [new file with mode: 0644]
include/tr_msg.h
include/trust_router/tid.h
tid/tidc.c
tid/tids.c
tr/tr.c
tr/tr_main.c

diff --git a/README b/README
index 281daf4..8a084e4 100644 (file)
--- a/README
+++ b/README
@@ -14,13 +14,13 @@ DONE - Generate a real random number for DH (in common/tr_dh.c)
 DONE - Read TR portal/manual config from files at start-up (non-dynamic)
 DONE - Look-up code to find correct AAA Server for a Comm/Realm
 IN PROGRESS - TR TID request & response handlers
-IN PROGRESS - TIDS integration with freeradius server (Sam)
-IN PROGRESS - TIDC integration with freeradius proxy (incl default comm config)
-- Handle community configuration in AAA proxy (per-request config)
-- Map a COI to an APC in TR (incl config & lookup code)
+- Check gss_name on incoming TID request in TR (in TIDS, too?)
 - Check rp_realm COI membership in TR 
 - Check idp_realm APC membership in TR 
-- Check gss_name in TR
+- Map a COI to an APC in TR (incl config & lookup code)
+IN PROGRESS - TIDS integration with freeradius server (Sam)
+IN PROGRESS - TIDC integration with freeradius proxy (incl default comm config)
+- Handle per-request community configuration in AAA proxy
 - Resolve TBDs for error handling and memory deallocation
 
 TO-DO FOR FULL PILOT VERSION (~2 months after beta release)
index 61ceb3d..8ca9c37 100644 (file)
 typedef struct tr_instance {
   struct tr_cfg *new_cfg;      /* unapplyed configuration */
   struct tr_cfg *active_cfg;
-  TIDC_INSTANCE tidc;
-  TIDS_INSTANCE tids;
+  TIDS_INSTANCE *tids;
 } TR_INSTANCE;
 
 TR_INSTANCE *tr_create(void);
+void tr_destroy(TR_INSTANCE *tr);
 
 #endif
diff --git a/include/tr_idp.h b/include/tr_idp.h
new file mode 100644 (file)
index 0000000..0788d82
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef TR_IDP_H
+#define TR_IDP_H
+
+#include <trust_router/tr_name.h>
+#include <tr.h>
+
+typedef struct tr_apc {
+  struct tr_apc *next;
+  TR_NAME *apc;
+} TR_APC;
+
+typedef struct tr_aaa_server {
+  struct tr_aaa_server *next;
+  struct in_addr aaa_server_addr;
+} TR_AAA_SERVER;
+
+typedef struct tr_idp_realm {
+  struct tr_idp_realm *next;
+  TR_NAME *realm_id;
+  int shared_config;
+  TR_AAA_SERVER *aaa_servers;
+  TR_APC *apcs;
+} TR_IDP_REALM;
+  
+TR_AAA_SERVER *tr_idp_aaa_server_lookup(TR_INSTANCE *tr, TR_NAME *idp_realm, TR_NAME *comm);
+
+#endif
index 1ab2c72..bfd0da7 100644 (file)
@@ -35,8 +35,9 @@
 #ifndef TR_MSG_H
 #define TR_MSG_H
 
-#include <trust_router/tid.h>
 #include <jansson.h>
+#include <trust_router/tr_versioning.h>
+#include <trust_router/tid.h>
 
 enum msg_type {
   TR_UNKNOWN = 0,
index 0001bd1..caf02e7 100644 (file)
@@ -45,8 +45,6 @@
 
 typedef struct gss_ctx_id_struct *gss_ctx_id_t;
 
-typedef struct tid_req TID_REQ;
-
 typedef enum tid_rc {
   TID_SUCCESS = 0,
   TID_ERROR
@@ -79,6 +77,8 @@ typedef void (TIDC_RESP_FUNC)(TIDC_INSTANCE *, TID_REQ *, TID_RESP *, void *);
 struct tid_req {
   struct tid_req *next_req;
   int conn;
+  gss_ctx_id_t *gssctx;
+  int resp_rcvd;
   TR_NAME *rp_realm;
   TR_NAME *realm;
   TR_NAME *comm;
@@ -107,6 +107,7 @@ struct tids_instance {
 TR_EXPORT TIDC_INSTANCE *tidc_create (void);
 TR_EXPORT int tidc_open_connection (TIDC_INSTANCE *tidc, char *server, gss_ctx_id_t *gssctx);
 TR_EXPORT int tidc_send_request (TIDC_INSTANCE *tidc, int conn, gss_ctx_id_t gssctx, char *rp_realm, char *realm, char *coi, TIDC_RESP_FUNC *resp_handler, void *cookie);
+TR_EXPORT int tids_send_response (TIDS_INSTANCE *tids, int conn, gss_ctx_id_t *gssctx, TID_RESP *resp);
 TR_EXPORT void tidc_destroy (TIDC_INSTANCE *tidc);
 
 TR_EXPORT TIDS_INSTANCE *tids_create (void);
index 3f96249..cf87bbc 100644 (file)
@@ -129,6 +129,7 @@ int tidc_send_request (TIDC_INSTANCE *tidc,
   msg->tid_req = tid_req;
 
   tid_req->conn = conn;
+  tid_req->gssctx = gssctx;
 
   /* TBD -- error handling */
   tid_req->rp_realm = tr_new_name(rp_realm);
index 842c983..3e13394 100644 (file)
@@ -41,9 +41,9 @@
 #include <netinet/in.h>
 #include <jansson.h>
 
+#include <trust_router/tid.h>
 #include <gsscon.h>
 #include <tr_msg.h>
-#include <trust_router/tid.h>
 
 static int tids_listen (TIDS_INSTANCE *tids, int port) 
 {
@@ -124,10 +124,9 @@ static int tids_read_request (TIDS_INSTANCE *tids, int conn, gss_ctx_id_t *gssct
   return buflen;
 }
 
-static int tids_handle_request (TIDS_INSTANCE *tids, TR_MSG *mreq, TR_MSG **mresp) 
+static int tids_handle_request (TIDS_INSTANCE *tids, TR_MSG *mreq, TID_RESP **resp) 
 {
   int rc;
-  TID_RESP *resp;
 
   /* Check that this is a valid TID Request.  If not, send an error return. */
   if ((!mreq->tid_req) ||
@@ -135,35 +134,38 @@ static int tids_handle_request (TIDS_INSTANCE *tids, TR_MSG *mreq, TR_MSG **mres
       (!mreq->tid_req->realm) ||
       (!mreq->tid_req->comm)) {
     printf("tids_handle_request():Not a valid TID Request.\n");
-    (*mresp)->tid_resp->result = TID_ERROR;
-    (*mresp)->tid_resp->err_msg = tr_new_name("Bad request format");
+    (*resp)->result = TID_ERROR;
+    (*resp)->err_msg = tr_new_name("Bad request format");
     return -1;
   }
 
   /* Call the caller's request handler */
   /* TBD -- Handle different error returns/msgs */
-  resp = (*mresp)->tid_resp;
-  if (0 > (rc = (*tids->req_handler)(tids, mreq->tid_req, &resp, tids->cookie))) {
+  if (0 > (rc = (*tids->req_handler)(tids, mreq->tid_req, &(*resp), tids->cookie))) {
     /* set-up an error response */
-    (*mresp)->tid_resp->result = TID_ERROR;
-    if (!(*mresp)->tid_resp->err_msg)  /* Use msg set by handler, if any */
-      (*mresp)->tid_resp->err_msg = tr_new_name("Internal processing error");
+    (*resp)->result = TID_ERROR;
+    if (!(*resp)->err_msg)     /* Use msg set by handler, if any */
+      (*resp)->err_msg = tr_new_name("Internal processing error");
   }
   else {
     /* set-up a success response */
-    (*mresp)->tid_resp->result = TID_SUCCESS;
-    (*mresp)->tid_resp->err_msg = NULL;        /* No msg on successful return */
+    (*resp)->result = TID_SUCCESS;
+    (*resp)->err_msg = NULL;   /* No msg on successful return */
   }
     
   return rc;
 }
 
-static int tids_send_response (TIDS_INSTANCE *tids, int conn, gss_ctx_id_t *gssctx, TR_MSG *mresp)
+int tids_send_response (TIDS_INSTANCE *tids, int conn, gss_ctx_id_t *gssctx, TID_RESP *resp)
 {
   int err;
+  TR_MSG mresp;
   char *resp_buf;
 
-  if (NULL == (resp_buf = tr_msg_encode(mresp))) {
+  mresp.msg_type = TID_RESPONSE;
+  mresp.tid_resp = resp;
+  
+  if (NULL == (resp_buf = tr_msg_encode(&mresp))) {
     fprintf(stderr, "Error decoding json response.\n");
     return -1;
   }
@@ -185,7 +187,7 @@ static int tids_send_response (TIDS_INSTANCE *tids, int conn, gss_ctx_id_t *gssc
 static void tids_handle_connection (TIDS_INSTANCE *tids, int conn)
 {
   TR_MSG *mreq = NULL;
-  TR_MSG *mresp = NULL;
+  TID_RESP *resp = NULL;
   int rc = 0;
   gss_ctx_id_t gssctx = GSS_C_NO_CONTEXT;
 
@@ -207,29 +209,25 @@ static void tids_handle_connection (TIDS_INSTANCE *tids, int conn)
     }
 
     /* Allocate a response structure and populate common fields */
-    if ((NULL == (mresp = malloc(sizeof(TR_MSG)))) ||
-       (NULL == (mresp->tid_resp = malloc(sizeof(TID_RESP))))) {
+    if ((NULL == (resp = malloc(sizeof(TID_RESP))))) {
       fprintf(stderr, "Error allocating response structure.\n");
       return;
     }
 
-    mresp->msg_type = TID_RESPONSE;
-    memset(mresp->tid_resp, 0, sizeof(TID_RESP));
-
     /* TBD -- handle errors */
-    mresp->tid_resp->result = TID_SUCCESS; /* presume success */
-    mresp->tid_resp->rp_realm = tr_dup_name(mreq->tid_req->rp_realm);
-    mresp->tid_resp->realm = tr_dup_name(mreq->tid_req->realm);
-    mresp->tid_resp->comm = tr_dup_name(mreq->tid_req->comm);
+    resp->result = TID_SUCCESS; /* presume success */
+    resp->rp_realm = tr_dup_name(mreq->tid_req->rp_realm);
+    resp->realm = tr_dup_name(mreq->tid_req->realm);
+    resp->comm = tr_dup_name(mreq->tid_req->comm);
     if (mreq->tid_req->orig_coi)
-      mresp->tid_resp->orig_coi = tr_dup_name(mreq->tid_req->orig_coi);
+      resp->orig_coi = tr_dup_name(mreq->tid_req->orig_coi);
 
-    if (0 > (rc = tids_handle_request(tids, mreq, &mresp))) {
+    if (0 > (rc = tids_handle_request(tids, mreq, &resp))) {
       fprintf(stderr, "Error from tids_handle_request(), rc = %d.\n", rc);
       return;
     }
 
-    if (0 > (rc = tids_send_response(tids, conn, &gssctx, mresp))) {
+    if (0 > (rc = tids_send_response(tids, conn, &gssctx, resp))) {
       fprintf(stderr, "Error from tids_send_response(), rc = %d.\n", rc);
       return;
     }
diff --git a/tr/tr.c b/tr/tr.c
index 5243bc4..09438f7 100644 (file)
--- a/tr/tr.c
+++ b/tr/tr.c
@@ -42,3 +42,7 @@ TR_INSTANCE *tr_create() {
     memset(tr, 0, sizeof(TR_INSTANCE));
   return tr;
 }
+
+void tr_destroy(TR_INSTANCE *tr) {
+  free (tr);
+}
index 4f330ae..36f5a89 100644 (file)
 #include <tr.h>
 #include <trust_router/tid.h>
 #include <tr_config.h>
+#include <tr_idp.h>
 
+/* Structure to hold TR instance and original request in one cookie */
+typedef struct tr_resp_cookie {
+  TR_INSTANCE *tr;
+  TID_REQ *orig_req;
+} TR_RESP_COOKIE;
 
-static int tids_req_handler (TIDS_INSTANCE * tids,
+static void tr_tidc_resp_handler (TIDC_INSTANCE *tidc, 
+                       TID_REQ *req,
+                       TID_RESP *resp, 
+                       void *resp_cookie) 
+{
+  fprintf(stderr, "tr_tidc_resp_handler: Response received! Realm = %s, Community = %s.\n", resp->realm->buf, resp->comm->buf);
+  req->resp_rcvd = 1;
+
+  /* TBD -- handle concatentation of multiple responses to single req */
+  tids_send_response(((TR_RESP_COOKIE *)resp_cookie)->tr->tids, ((TR_RESP_COOKIE *)resp_cookie)->orig_req->conn, ((TR_RESP_COOKIE *)resp_cookie)->orig_req->gssctx, resp);
+  
+  return;
+}
+
+static int tr_tids_req_handler (TIDS_INSTANCE * tids,
                      TID_REQ *req, 
                      TID_RESP **resp,
-                     void *cookie)
+                     void *tr)
 {
+  gss_ctx_id_t gssctx;
+  TIDC_INSTANCE *tidc = NULL;
+  TR_RESP_COOKIE resp_cookie;
+  TR_AAA_SERVER *aaa_servers = NULL;
+  int conn = 0;
+  int rc;
+
+  if ((!tids) || (!req) || (!resp) || (!(*resp))) {
+    printf("tids_req_handler: Bad parameters\n");
+    return -1;
+  }
+
   printf("Request received! Realm = %s, Comm = %s\n", req->realm->buf, req->comm->buf);
   if (tids)
     tids->req_count++;
 
+  /* find the AAA server(s) for this request */
+  aaa_servers = tr_idp_aaa_server_lookup((TR_INSTANCE *)tids->cookie, req->realm, req->comm);
+  /* send a TID request to the AAA server(s), and get the answer(s) */
+  /* TBD -- Handle multiple servers */
+
+  /* Create a TID client instance */
+  if (NULL == (tidc = tidc_create())) {
+    fprintf(stderr, "tr_tids_req_hander: Unable to allocate TIDC instance.\n");
+    return -1;
+  }
+
+  /* Set-up TID connection */
+  /* TBD -- version of open_connection that takes an inaddr */
+  if (-1 == (conn = tidc_open_connection(tidc, inet_ntoa(aaa_servers->aaa_server_addr), &gssctx))) {
+    printf("tr_tids_req_handler: Error in tidc_open_connection.\n");
+    return -1;
+  };
+
+  /* Send a TID request */
+  resp_cookie.tr = tr;
+  resp_cookie.orig_req = req;
+
+  /* TBD -- version of send request that takes TR_NAMES */
+  if (0 > (rc = tidc_send_request(tidc, conn, gssctx, req->rp_realm->buf, req->realm->buf, req->comm->buf, &tr_tidc_resp_handler, (void *)&resp_cookie))) {
+    printf("Error in tidc_send_request, rc = %d.\n", rc);
+    return -1;
+  }
+    
   return 0;
 }
 
 int main (int argc, const char *argv[])
 {
   TR_INSTANCE *tr = NULL;
-  TIDS_INSTANCE *tids = NULL;
   struct dirent **cfg_files = NULL;
   json_t *jcfg = NULL;
   TR_CFG_RC rc = TR_CFG_SUCCESS;       /* presume success */
@@ -91,20 +150,19 @@ int main (int argc, const char *argv[])
     exit(1);
   }
 
-  //  printf("Trust Router Configured, max_tree_depth = %d.\n", tr->active_cfg->internal->max_tree_depth);
-
   /* initialize the trust path query server instance */
-  if (0 == (tids = tids_create ())) {
+  if (0 == (tr->tids = tids_create ())) {
     printf ("Error initializing Trust Path Query Server instance.\n");
-    return 1;
+    exit(1);
   }
 
   /* start the trust path query server, won't return unless error. */
-  if (0 != (err = tids_start(tids, &tids_req_handler, NULL))) {
+  if (0 != (err = tids_start(tr->tids, &tr_tids_req_handler, (void *)tr))) {
     printf ("Error starting Trust Path Query Server, err = %d.\n", err);
-    return err;
+    exit(err);
   }
 
-  tids_destroy(tids);
-  return 0;
+  tids_destroy(tr->tids);
+  tr_destroy(tr);
+  exit(0);
 }