Code for TR to change a COI to an APC in forwarded reqs, also some reorg of request...
authorMargaret Wasserman <margaret@moonshot-proxy.(none)>
Tue, 30 Apr 2013 18:14:30 +0000 (14:14 -0400)
committerMargaret Wasserman <margaret@moonshot-proxy.(none)>
Tue, 30 Apr 2013 18:14:30 +0000 (14:14 -0400)
README
common/tr_comm.c [new file with mode: 0644]
include/tr_comm.h
include/trust_router/tid.h
tid/tidc.c
tr/manual.cfg [new file with mode: 0644]
tr/portal.cfg [new file with mode: 0644]
tr/tr_main.c

diff --git a/README b/README
index 1d33ca7..0001a90 100644 (file)
--- a/README
+++ b/README
@@ -14,29 +14,37 @@ 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
 DONE - TR TID request & response handlers
-- Check gss_name on incoming TID request in TR (in TIDS, too?)
+DONE - TIDS integration with freeradius server 
+DONE - TIDC integration with freeradius proxy 
+DONE - Map a COI to an APC in TR (incl config & lookup code)
 - Check rp_realm COI membership in TR 
 - Check idp_realm APC membership 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 (w/default comm config)
-- Handle per-request community configuration in AAA proxy
-- Resolve TBDs for error handling and memory deallocation
+DONE - Resolve TBDs for error handling and deallocation
 
 TO-DO FOR FULL PILOT VERSION (~2 months after beta release)
 ============================
-- Move to better tasking model for TR (needed for dyn cfg and TR protocol)
-- Dynamically re-read TR configuration file at runtime
+- Add key confirmation to TID protocol
+- Check gss_name on incoming TID request in TR (in TIDS, too?)
 - Keep single connection open between AAA proxy & TR for TID requests
-- Handle multiple simultaneous TID requests in AAA proxy (reqs req ID in the protocol)
+- Add Request ID to TID messages (req'd for mult simultaneous reqs)
+- Handle multiple simultaneous TID requests in AAA proxy 
+- Fix issue with how DH params are handled in the TR (API clean-up)
+- Handle per-request community configuration in AAA proxy
 - Add TR support for multiple AAA servers in an IDP
-- Normalize/configure logging for info msgs, warnings and errors (log4c)
+- Move to better tasking model for TR (for dyn cfg and TR protocol)
+- Dynamically re-read TR configuration file at runtime
+- Normalize/configure logging for info, warnings and errors (log4c)
 - Clean-up gsscon API and messages
+- Add accessors for all externally accessible data structures, etc.
+- Formalize API for integration with RADIUS servers
+- More fully integrate TIDS with AAA Server? (Tradeoffs?)
 - Figure out what to do about commented-out checks in gsscon_passive.c
 - Handle IPv6 addresses in TID req/resp (use getaddrinfo())
 - Implement rp_permitted filters (incl. general filtering mechanism)
+- Add 
 - Add constraints to TID req in TR, store and use them in AAA Server
 - Use valgrind to check for memory leaks, other issues
+- Resolve remaining TBDs
 - Full functional testing
 
 TO-DO FOR PRODUCTION VERSION (August 2013)
@@ -44,3 +52,4 @@ TO-DO FOR PRODUCTION VERSION (August 2013)
 - Multiple Trust Router support including implementation of TR protocol
 - Consider standard encoding of DH info (from jose WG)
 - Algorithm agility in TID protocol?
+- Handle more than one APC per COI? (How would this work?)
\ No newline at end of file
diff --git a/common/tr_comm.c b/common/tr_comm.c
new file mode 100644 (file)
index 0000000..660ed4b
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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 <trust_router/tr_name.h>
+#include <tr.h>
+#include <tr_comm.h>
+
+TR_COMM *tr_comm_lookup(TR_INSTANCE *tr, TR_NAME *comm) 
+{
+  return NULL;
+}
index 365f7ca..f0fa8f0 100644 (file)
@@ -54,4 +54,6 @@ typedef struct tr_comm {
   TR_RP_REALM *rp_realms;
 } TR_COMM;
 
+TR_COMM *tr_comm_lookup(TR_INSTANCE *tr, TR_NAME *comm);
+
 #endif
index 428eaca..c1778fc 100644 (file)
@@ -106,9 +106,12 @@ struct tids_instance {
   void *cookie;
 };
 
+TR_EXPORT TID_REQ *tid_dup_req (TID_REQ *orig_req);
+
 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 tidc_fwd_request (TIDC_INSTANCE *tidc, TID_REQ *req, 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);
 
index 764990f..06ae220 100644 (file)
@@ -62,6 +62,24 @@ void tidc_destroy (TIDC_INSTANCE *tidc)
     free(tidc);
 }
 
+TID_REQ *tid_dup_req (TID_REQ *orig_req) 
+{
+  TID_REQ *new_req;
+
+  if (NULL == (new_req = malloc(sizeof(TID_REQ))))
+    return NULL;
+
+  /* Memcpy for flat fields, not valid until names are duped. */
+  memcpy(new_req, orig_req, sizeof(TID_REQ));
+  
+  new_req->rp_realm = tr_dup_name(orig_req->rp_realm);
+  new_req->realm = tr_dup_name(orig_req->realm);
+  new_req->comm = tr_dup_name(orig_req->comm);
+  new_req->orig_coi = tr_dup_name(orig_req->orig_coi);
+
+  return new_req;
+}
+
 int tidc_open_connection (TIDC_INSTANCE *tidc, 
                          char *server,
                          gss_ctx_id_t *gssctx)
@@ -90,37 +108,50 @@ int tidc_send_request (TIDC_INSTANCE *tidc,
                       void *cookie)
 
 {
-  int err = 0;
-  char *req_buf = NULL;
-  char *resp_buf = NULL;
-  size_t resp_buflen = 0;
-  TR_MSG *msg = NULL;
   TID_REQ *tid_req = NULL;
-  TR_MSG *resp_msg = NULL;
 
-  /* Create and populate a TID msg structure */
-  if ((!(msg = malloc(sizeof(TR_MSG)))) ||
-      (!(tid_req = malloc(sizeof(TID_REQ)))))
+  /* Create and populate a TID req structure */
+  if (!(tid_req = malloc(sizeof(TID_REQ))))
     return -1;
 
   memset(tid_req, 0, sizeof(tid_req));
 
-  msg->msg_type = TID_REQUEST;
-
-  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);
-  tid_req->realm = tr_new_name(realm);
-  tid_req->comm = tr_new_name(comm);
+  if ((NULL == (tid_req->rp_realm = tr_new_name(rp_realm))) ||
+      (NULL == (tid_req->realm = tr_new_name(realm))) ||
+      (NULL == (tid_req->comm = tr_new_name(comm)))) {
+    fprintf (stderr, "tidc_send_request: Error duplicating names.\n");
+    return -1;
+  }
 
   tid_req->tidc_dh = tidc->client_dh;
-
   tid_req->resp_func = resp_handler;
   tid_req->cookie = cookie;
+  
+  return (tidc_fwd_request(tidc, tid_req, resp_handler, cookie));
+}
+
+int tidc_fwd_request (TIDC_INSTANCE *tidc, 
+                     TID_REQ *tid_req, 
+                     TIDC_RESP_FUNC *resp_handler,
+                     void *cookie)
+
+{
+  char *req_buf = NULL;
+  char *resp_buf = NULL;
+  size_t resp_buflen = 0;
+  TR_MSG *msg = NULL;
+  TR_MSG *resp_msg = NULL;
+  int err;
+
+  /* Create and populate a TID msg structure */
+  if (!(msg = malloc(sizeof(TR_MSG))))
+    return -1;
+
+  msg->msg_type = TID_REQUEST;
+  msg->tid_req = tid_req;
 
   /* Encode the request into a json string */
   if (!(req_buf = tr_msg_encode(msg))) {
@@ -132,16 +163,17 @@ int tidc_send_request (TIDC_INSTANCE *tidc,
   printf ("%s\n", req_buf);
 
   /* Send the request over the connection */
-  if (err = gsscon_write_encrypted_token (conn, gssctx, req_buf, 
+  if (err = gsscon_write_encrypted_token (tid_req->conn, tid_req->gssctx, req_buf, 
                                          strlen(req_buf))) {
     fprintf(stderr, "Error sending request over connection.\n");
     return -1;
   }
 
-  /* TBD -- should queue request on instance, resps read in separate thread */
-  /* Read the response from the connection */
+  /* TBD -- queue request on instance, read resps in separate thread */
 
-  if (err = gsscon_read_encrypted_token(conn, gssctx, &resp_buf, &resp_buflen)) {
+  /* Read the response from the connection */
+  /* TBD -- timeout? */
+  if (err = gsscon_read_encrypted_token(tid_req->conn, tid_req->gssctx, &resp_buf, &resp_buflen)) {
     if (resp_buf)
       free(resp_buf);
     return -1;
diff --git a/tr/manual.cfg b/tr/manual.cfg
new file mode 100644 (file)
index 0000000..9f7d451
--- /dev/null
@@ -0,0 +1 @@
+{"tr_internal":{"max_tree_depth": 4}}
\ No newline at end of file
diff --git a/tr/portal.cfg b/tr/portal.cfg
new file mode 100644 (file)
index 0000000..b096938
--- /dev/null
@@ -0,0 +1,207 @@
+{
+    "communities": [
+        {
+            "apcs": [], 
+            "community_id": "pci-community.ja.net", 
+            "idp_realms": [], 
+            "rp_realms": [], 
+            "type": "apc"
+        }, 
+        {
+            "apcs": [], 
+            "community_id": "community.ja.net", 
+            "idp_realms": [], 
+            "rp_realms": [], 
+            "type": "apc"
+        }, 
+        {
+            "apcs": [
+                "pci-community.ja.net"
+            ], 
+            "community_id": "comm.offcenter.org", 
+            "idp_realms": [
+                "idr2.offcenter.org"
+            ], 
+            "rp_realms": [
+                "sr3.offcenter.org"
+            ], 
+            "type": "coi"
+        }
+    ], 
+    "idp_realms": [
+        {
+            "aaa_servers": ["10.1.10.90"], 
+            "apcs": ["community.ja.net"], 
+            "realm_id": "ja.net", 
+            "shared_config": "no"
+        }, 
+        {
+            "aaa_servers": ["127.0.0.1"], 
+            "apcs": ["community.ja.net"], 
+            "realm_id": "idr2.offcenter.org", 
+            "shared_config": "no"
+        }, 
+        {
+            "aaa_servers": ["127.0.0.1"], 
+            "apcs": ["community.ja.net"], 
+            "realm_id": "idr1.offcenter.org", 
+            "shared_config": "yes"
+        }, 
+        {
+            "aaa_servers": ["127.0.0.1"], 
+            "apcs": ["community.ja.net"], 
+            "realm_id": "no-longer-untitled.offcenter.org", 
+            "shared_config": "yes"
+        }
+    ], 
+    "rp_clients": [
+        {
+            "filter": {
+                "filter_lines": [
+                    {
+                        "action": "accept", 
+                        "domain_constraints": [], 
+                        "filter_specs": [
+                            {
+                                "field": "rp_realm", 
+                                "rp_realm": "*.exchange.ja.net"
+                            }
+                        ], 
+                        "realm_constraints": []
+                    }
+                ], 
+                "type": "rp_permitted"
+            }, 
+            "gss_names": [
+                "this.is.a.dandy.gss.name@creds.portal.ja.net"
+            ]
+        }, 
+        {
+            "filter": {
+                "filter_lines": [
+                    {
+                        "action": "accept", 
+                        "domain_constraints": [], 
+                        "filter_specs": [
+                            {
+                                "field": "rp_realm", 
+                                "rp_realm": "*.sr3.offcenter.org"
+                            }
+                        ], 
+                        "realm_constraints": []
+                    }
+                ], 
+                "type": "rp_permitted"
+            }, 
+            "gss_names": [
+                "this.is.a.dandy.gss.name@creds.portal.ja.net"
+            ]
+        }, 
+        {
+            "filter": {
+                "filter_lines": [
+                    {
+                        "action": "accept", 
+                        "domain_constraints": [], 
+                        "filter_specs": [
+                            {
+                                "field": "rp_realm", 
+                                "rp_realm": "*.shell.ja.net"
+                            }
+                        ], 
+                        "realm_constraints": []
+                    }
+                ], 
+                "type": "rp_permitted"
+            }, 
+            "gss_names": [
+                "this.is.a.dandy.gss.name@creds.portal.ja.net"
+            ]
+        }, 
+        {
+            "filter": {
+                "filter_lines": [
+                    {
+                        "action": "accept", 
+                        "domain_constraints": [], 
+                        "filter_specs": [
+                            {
+                                "field": "rp_realm", 
+                                "rp_realm": "*.sr2.offcenter.org"
+                            }
+                        ], 
+                        "realm_constraints": []
+                    }
+                ], 
+                "type": "rp_permitted"
+            }, 
+            "gss_names": [
+                "this.is.a.dandy.gss.name@creds.portal.ja.net"
+            ]
+        }, 
+        {
+            "filter": {
+                "filter_lines": [
+                    {
+                        "action": "accept", 
+                        "domain_constraints": [], 
+                        "filter_specs": [
+                            {
+                                "field": "rp_realm", 
+                                "rp_realm": "*.sr1.offcenter.org"
+                            }
+                        ], 
+                        "realm_constraints": []
+                    }
+                ], 
+                "type": "rp_permitted"
+            }, 
+            "gss_names": [
+                "this.is.a.dandy.gss.name@creds.portal.ja.net"
+            ]
+        }, 
+        {
+            "filter": {
+                "filter_lines": [
+                    {
+                        "action": "accept", 
+                        "domain_constraints": [], 
+                        "filter_specs": [
+                            {
+                                "field": "rp_realm", 
+                                "rp_realm": "*.sr4.offcenter.org"
+                            }
+                        ], 
+                        "realm_constraints": []
+                    }
+                ], 
+                "type": "rp_permitted"
+            }, 
+            "gss_names": [
+                "this.is.a.dandy.gss.name@creds.portal.ja.net"
+            ]
+        }, 
+        {
+            "filter": {
+                "filter_lines": [
+                    {
+                        "action": "accept", 
+                        "domain_constraints": [], 
+                        "filter_specs": [
+                            {
+                                "field": "rp_realm", 
+                                "rp_realm": "*.billing.ja.net"
+                            }
+                        ], 
+                        "realm_constraints": []
+                    }
+                ], 
+                "type": "rp_permitted"
+            }, 
+            "gss_names": [
+                "this.is.a.dandy.gss.name@creds.portal.ja.net"
+            ]
+        }
+    ]
+}
+
index ce1cc49..49b4eeb 100644 (file)
@@ -38,6 +38,7 @@
 #include <tr.h>
 #include <trust_router/tid.h>
 #include <tr_config.h>
+#include <tr_comm.h>
 #include <tr_idp.h>
 
 /* Structure to hold TR instance and original request in one cookie */
@@ -61,28 +62,53 @@ static void tr_tidc_resp_handler (TIDC_INSTANCE *tidc,
 }
 
 static int tr_tids_req_handler (TIDS_INSTANCE * tids,
-                     TID_REQ *req, 
+                     TID_REQ *orig_req, 
                      TID_RESP **resp,
                      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;
+  TR_NAME *apc = NULL;
+  TID_REQ *req = NULL;
+  TR_COMM *cfg_comm = NULL;
   int rc;
 
-  if ((!tids) || (!req) || (!resp) || (!(*resp))) {
+  if ((!tids) || (!orig_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);
+  printf("Request received! Realm = %s, Comm = %s\n", orig_req->realm->buf, orig_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);
+  /* Save tr and request info for the response */
+  resp_cookie.tr = tr;
+  resp_cookie.orig_req = req;
+
+  /* Duplicate the request, so we can modify and forward it */
+  if (NULL == (req = tid_dup_req(orig_req))) {
+    fprintf(stderr, "tr_tids_req_handler: Unable to duplicate request.\n");
+    return -1;
+  }
+
+  /* Map the comm in the request from a COI to an APC, if needed */
+  if (NULL == (cfg_comm = tr_comm_lookup((TR_INSTANCE *)tids->cookie, req->comm))) {
+    fprintf(stderr, "tr_tids_req_hander: Request for unknown comm: %s.\n", req->comm->buf);
+  }
+
+  /* TBD -- check that the rp_realm is a member of the original community */
+
+  if (TR_COMM_COI == cfg_comm->type) {
+    /* TBD -- In theory there can be more than one?  How would that work? */
+    apc = tr_dup_name(cfg_comm->apcs->id);
+    req->orig_coi = req->comm;
+    req->comm = apc;
+  }
+
+  /* Find the AAA server(s) for this request */
+  aaa_servers = tr_idp_aaa_server_lookup((TR_INSTANCE *)tids->cookie, req->realm, apc);
   /* send a TID request to the AAA server(s), and get the answer(s) */
   /* TBD -- Handle multiple servers */
 
@@ -93,22 +119,24 @@ static int tr_tids_req_handler (TIDS_INSTANCE * tids,
   }
 
   /* Use the DH parameters from the original request */
+  /* TBD -- this needs to be fixed when we handle more than one req per conn */
   tidc->client_dh = req->tidc_dh;
 
+  /* Save information about this request for the response */
+  resp_cookie.tr = tr;
+  resp_cookie.orig_req = req;
+
   /* 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))) {
+  /* TBD -- handle IPv6 Addresses */
+  if (-1 == (req->conn = tidc_open_connection(tidc, inet_ntoa(aaa_servers->aaa_server_addr), &(req->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);
+  if (0 > (rc = tidc_fwd_request(tidc, req, &tr_tidc_resp_handler, (void *)&resp_cookie))) {
+    printf("Error from tidc_fwd_request, rc = %d.\n", rc);
     return -1;
   }