From 90d9e3659318270c28a7ea8bf018e07512901a06 Mon Sep 17 00:00:00 2001 From: Margaret Wasserman Date: Fri, 3 May 2013 16:56:55 -0400 Subject: [PATCH] Improved error handling, cleaned up messages, fixed minor bugs. --- common/tr_comm.c | 8 +++ common/tr_name.c | 9 ++- include/tr_apc.h | 46 ++++++++++++++ include/trust_router/tid.h | 4 +- tid/example/tids_main.c | 62 +++++++++---------- tid/tidc.c | 52 ++++++++++------ tid/tids.c | 146 ++++++++++++++++++++++++++++++++++----------- tr/tr_main.c | 66 ++++++++++++-------- 8 files changed, 279 insertions(+), 114 deletions(-) create mode 100644 include/tr_apc.h diff --git a/common/tr_comm.c b/common/tr_comm.c index 660ed4b..9ad35b3 100644 --- a/common/tr_comm.c +++ b/common/tr_comm.c @@ -33,10 +33,18 @@ */ #include +#include #include #include TR_COMM *tr_comm_lookup(TR_INSTANCE *tr, TR_NAME *comm) { + TR_COMM *cfg_comm = NULL; + + for (cfg_comm = tr->active_cfg->comms; NULL != cfg_comm; cfg_comm = cfg_comm->next) { + if ((cfg_comm->id->len == comm->len) && + (!strncmp(cfg_comm->id->buf, comm->buf, comm->len))) + return cfg_comm; + } return NULL; } diff --git a/common/tr_name.c b/common/tr_name.c index 00757d4..0e15595 100644 --- a/common/tr_name.c +++ b/common/tr_name.c @@ -64,14 +64,17 @@ TR_NAME *tr_dup_name (TR_NAME *from) { TR_NAME *to; - if (to = malloc(sizeof(TR_NAME))) { + if (!from) { + return NULL; + } + + if (NULL != (to = malloc(sizeof(TR_NAME)))) { to->len = from->len; - if (to->buf = malloc(to->len+1)) { + if (NULL != (to->buf = malloc(to->len+1))) { strncpy(to->buf, from->buf, from->len); to->buf[to->len] = 0; /* NULL terminate for debugging printf()s */ } } - return to; } diff --git a/include/tr_apc.h b/include/tr_apc.h new file mode 100644 index 0000000..a417459 --- /dev/null +++ b/include/tr_apc.h @@ -0,0 +1,46 @@ +/* + * 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_APC_H +#define TR_APC_H + +/* Used to hold lists of APC names in cfg. */ +typedef struct tr_apc { + struct tr_apc *next; + TR_NAME *id; +} TR_APC; + +#endif + + diff --git a/include/trust_router/tid.h b/include/trust_router/tid.h index 0a7baff..aaadaf7 100644 --- a/include/trust_router/tid.h +++ b/include/trust_router/tid.h @@ -77,6 +77,7 @@ typedef void (TIDC_RESP_FUNC)(TIDC_INSTANCE *, TID_REQ *, TID_RESP *, void *); struct tid_req { struct tid_req *next_req; + int resp_sent; int conn; gss_ctx_id_t gssctx; int resp_rcvd; @@ -113,11 +114,12 @@ 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); TR_EXPORT TIDS_INSTANCE *tids_create (void); TR_EXPORT int tids_start (TIDS_INSTANCE *tids, TIDS_REQ_FUNC *req_handler, void *cookie); +TR_EXPORT int tids_send_response (TIDS_INSTANCE *tids, TID_REQ *req, TID_RESP *resp); +TR_EXPORT int tids_send_err_response (TIDS_INSTANCE *tids, TID_REQ *req, const char *err_msg); TR_EXPORT void tids_destroy (TIDS_INSTANCE *tids); #endif diff --git a/tid/example/tids_main.c b/tid/example/tids_main.c index 06a2831..b57c4e3 100644 --- a/tid/example/tids_main.c +++ b/tid/example/tids_main.c @@ -70,22 +70,21 @@ static int tids_req_handler (TIDS_INSTANCE * tids, { unsigned char *s_keybuf = NULL; int s_keylen = 0; - int i = 0; char key_id[12]; - printf("Request received! target_realm = %s, community = %s\n", req->realm->buf, req->comm->buf); + fprintf(stdout, "tids_req_handler: Request received! target_realm = %s, community = %s\n", req->realm->buf, req->comm->buf); if (tids) tids->req_count++; if (!(resp) || !(*resp)) { - printf("tids_req_handler: No response structure.\n"); + fprintf(stderr, "tids_req_handler: No response structure.\n"); return -1; } /* Allocate a new server block */ if (NULL == ((*resp)->servers = malloc(sizeof(TID_SRVR_BLK)))){ - printf("tids_req_handler(): malloc failed.\n"); + fprintf(stderr, "tids_req_handler(): malloc failed.\n"); return -1; } memset((*resp)->servers, 0, sizeof(TID_SRVR_BLK)); @@ -93,26 +92,26 @@ static int tids_req_handler (TIDS_INSTANCE * tids, /* TBD -- Set up the server IP Address */ if (!(req) || !(req->tidc_dh)) { - printf("tids_req_handler(): No client DH info.\n"); + fprintf(stderr, "tids_req_handler(): No client DH info.\n"); return -1; } if ((!req->tidc_dh->p) || (!req->tidc_dh->g)) { - printf("tids_req_handler(): NULL dh values.\n"); + fprintf(stderr, "tids_req_handler(): NULL dh values.\n"); return -1; } /* Generate the server DH block based on the client DH block */ - printf("Generating the server DH block.\n"); - printf("...from client DH block, dh_g = %s, dh_p = %s.\n", BN_bn2hex(req->tidc_dh->g), BN_bn2hex(req->tidc_dh->p)); + // fprintf(stderr, "Generating the server DH block.\n"); + // fprintf(stderr, "...from client DH block, dh_g = %s, dh_p = %s.\n", BN_bn2hex(req->tidc_dh->g), BN_bn2hex(req->tidc_dh->p)); if (NULL == ((*resp)->servers->aaa_server_dh = tr_create_matching_dh(NULL, 0, req->tidc_dh))) { - printf("tids_req_handler(): Can't create server DH params.\n"); + fprintf(stderr, "tids_req_handler(): Can't create server DH params.\n"); return -1; } if (0 == inet_aton(tids->ipaddr, &((*resp)->servers->aaa_server_addr))) { - printf("tids_req_handler(): inet_aton() failed.\n"); + fprintf(stderr, "tids_req_handler(): inet_aton() failed.\n"); return -1; } @@ -122,30 +121,31 @@ static int tids_req_handler (TIDS_INSTANCE * tids, (*resp)->servers->key_name = tr_new_name(key_id); /* Generate the server key */ - printf("Generating the server key.\n"); + // fprintf(stderr, "Generating the server key.\n"); if (0 > (s_keylen = tr_compute_dh_key(&s_keybuf, req->tidc_dh->pub_key, (*resp)->servers->aaa_server_dh))) { - printf("tids_req_handler(): Key computation failed."); + fprintf(stderr, "tids_req_handler(): Key computation failed."); return -1; } - if (NULL != insert_stmt) { - int sqlite3_result; - sqlite3_bind_text(insert_stmt, 1, key_id, -1, SQLITE_TRANSIENT); - sqlite3_bind_blob(insert_stmt, 2, s_keybuf, s_keylen, SQLITE_TRANSIENT); - sqlite3_result = sqlite3_step(insert_stmt); - if (SQLITE_DONE != sqlite3_result) - printf("sqlite3: failed to write to database\n"); - sqlite3_reset(insert_stmt); - } - - /* Print out the key. If this were a AAA server, we'd store the key. */ - printf("tids_req_handler(): Server Key Generated (len = %d):\n", s_keylen); - for (i = 0; i < s_keylen; i++) { - printf("%x", s_keybuf[i]); + if (NULL != insert_stmt) { + int sqlite3_result; + sqlite3_bind_text(insert_stmt, 1, key_id, -1, SQLITE_TRANSIENT); + sqlite3_bind_blob(insert_stmt, 2, s_keybuf, s_keylen, SQLITE_TRANSIENT); + sqlite3_result = sqlite3_step(insert_stmt); + if (SQLITE_DONE != sqlite3_result) + printf("sqlite3: failed to write to database\n"); + sqlite3_reset(insert_stmt); } - printf("\n"); + + /* Print out the key. */ + // fprintf(stderr, "tids_req_handler(): Server Key Generated (len = %d):\n", s_keylen); + // for (i = 0; i < s_keylen; i++) { + // fprintf(stderr, "%x", s_keybuf[i]); + // } + // fprintf(stderr, "\n"); + return s_keylen; } @@ -158,7 +158,7 @@ int main (int argc, /* Parse command-line arguments */ if (argc > 3) - printf("Usage: %s [ []]\n", argv[0]); + fprintf(stdout, "Usage: %s [ []]\n", argv[0]); if (argc >= 2) { ipaddr = (char *)argv[1]; @@ -171,7 +171,7 @@ int main (int argc, /*If we have a database, open and prepare*/ if (argc == 3) { if (SQLITE_OK != sqlite3_open(argv[2], &db)) { - printf("Error opening database %s\n", argv[2]); + fprintf(stdout, "Error opening database %s\n", argv[2]); exit(1); } sqlite3_prepare_v2(db, "insert into psk_keys (keyid, key) values(?, ?)", @@ -180,7 +180,7 @@ int main (int argc, /* Create a TID server instance */ if (NULL == (tids = tids_create())) { - printf("Unable to create TIDS instance,exiting.\n"); + fprintf(stdout, "Unable to create TIDS instance,exiting.\n"); return 1; } @@ -189,7 +189,7 @@ int main (int argc, /* Start-up the server, won't return unless there is an error. */ rc = tids_start(tids, &tids_req_handler , NULL); - printf("Error in tids_start(), rc = %d. Exiting.\n", rc); + fprintf(stdout, "Error in tids_start(), rc = %d. Exiting.\n", rc); /* Clean-up the TID server instance */ tids_destroy(tids); diff --git a/tid/tidc.c b/tid/tidc.c index 5c3028f..79ba2f3 100644 --- a/tid/tidc.c +++ b/tid/tidc.c @@ -64,19 +64,28 @@ void tidc_destroy (TIDC_INSTANCE *tidc) TID_REQ *tid_dup_req (TID_REQ *orig_req) { - TID_REQ *new_req; + TID_REQ *new_req = NULL; - if (NULL == (new_req = malloc(sizeof(TID_REQ)))) + if (NULL == (new_req = malloc(sizeof(TID_REQ)))) { + fprintf(stderr, "tid_dup_req: Can't allocated duplicate request.\n"); 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); + if ((NULL == (new_req->rp_realm = tr_dup_name(orig_req->rp_realm))) || + (NULL == (new_req->realm = tr_dup_name(orig_req->realm))) || + (NULL == (new_req->comm = tr_dup_name(orig_req->comm)))) { + fprintf(stderr, "tid_dup_req: Can't duplicate request (names).\n"); + } + if (orig_req->orig_coi) { + if (NULL == (new_req->orig_coi = tr_dup_name(orig_req->orig_coi))) { + fprintf(stderr, "tid_dup_req: Can't duplicate request (orig_coi).\n"); + } + } + return new_req; } @@ -127,9 +136,7 @@ int tidc_send_request (TIDC_INSTANCE *tidc, } 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)); } @@ -153,19 +160,24 @@ int tidc_fwd_request (TIDC_INSTANCE *tidc, msg->msg_type = TID_REQUEST; msg->tid_req = tid_req; + /* store the response function and cookie */ + // tid_req->resp_func = resp_handler; + // tid_req->cookie = cookie; + + /* Encode the request into a json string */ if (!(req_buf = tr_msg_encode(msg))) { - printf("Error encoding TID request.\n"); + fprintf(stderr, "tidc_fwd_request: Error encoding TID request.\n"); return -1; } - printf ("Sending TID request:\n"); - printf ("%s\n", req_buf); + fprintf (stderr, "tidc_fwd_request: Sending TID request:\n"); + fprintf (stderr, "%s\n", req_buf); /* Send the request over the connection */ 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"); + fprintf(stderr, "tidc_fwd_request: Error sending request over connection.\n"); return -1; } @@ -179,23 +191,25 @@ int tidc_fwd_request (TIDC_INSTANCE *tidc, return -1; } - fprintf(stdout, "Response Received (%u bytes).\n", (unsigned) resp_buflen); + fprintf(stdout, "tidc_fwd_request: Response Received (%u bytes).\n", (unsigned) resp_buflen); fprintf(stdout, "%s\n", resp_buf); if (NULL == (resp_msg = tr_msg_decode(resp_buf, resp_buflen))) { - fprintf(stderr, "Error decoding response.\n"); + fprintf(stderr, "tidc_fwd_request: Error decoding response.\n"); return -1; } /* TBD -- Check if this is actually a valid response */ if (!resp_msg->tid_resp) { - fprintf(stderr, "Error: No response in the response!\n"); + fprintf(stderr, "tidc_fwd_request: Error, no response in the response!\n"); return -1; } - /* Call the caller's response function */ - (*tid_req->resp_func)(tidc, tid_req, resp_msg->tid_resp, cookie); - + if (resp_handler) + /* Call the caller's response function */ + (*resp_handler)(tidc, tid_req, resp_msg->tid_resp, cookie); + else + fprintf(stderr, "tidc_fwd_request: NULL response function.\n"); if (msg) free(msg); diff --git a/tid/tids.c b/tid/tids.c index c7a125f..1b50b54 100644 --- a/tid/tids.c +++ b/tid/tids.c @@ -45,6 +45,48 @@ #include #include +static TID_RESP *tids_create_response (TIDS_INSTANCE *tids, TID_REQ *req) +{ + TID_RESP *resp; + + if ((NULL == (resp = calloc(sizeof(TID_RESP), 1)))) { + fprintf(stderr, "tids_create_response: Error allocating response structure.\n"); + return NULL; + } + + resp->result = TID_SUCCESS; /* presume success */ + if ((NULL == (resp->rp_realm = tr_dup_name(req->rp_realm))) || + (NULL == (resp->realm = tr_dup_name(req->realm))) || + (NULL == (resp->comm = tr_dup_name(req->comm)))) { + fprintf(stderr, "tids_create_response: Error allocating fields in response.\n"); + return NULL; + } + if (req->orig_coi) { + if (NULL == (resp->orig_coi = tr_dup_name(req->orig_coi))) { + fprintf(stderr, "tids_create_response: Error allocating fields in response.\n"); + return NULL; + } + } + return resp; +} + +static void tids_destroy_response(TIDS_INSTANCE *tids, TID_RESP *resp) +{ + if (resp) { + if (resp->err_msg) + tr_free_name(resp->err_msg); + if (resp->rp_realm) + tr_free_name(resp->rp_realm); + if (resp->realm) + tr_free_name(resp->realm); + if (resp->comm) + tr_free_name(resp->comm); + if (resp->orig_coi) + tr_free_name(resp->orig_coi); + free (resp); + } +} + static int tids_listen (TIDS_INSTANCE *tids, int port) { int rc = 0; @@ -68,7 +110,7 @@ static int tids_listen (TIDS_INSTANCE *tids, int port) if (0 > (rc = listen(conn, 512))) return rc; - fprintf (stdout, "TID Server listening on port %d\n", port); + fprintf (stdout, "tids_listen: TID Server listening on port %d\n", port); return conn; } @@ -78,20 +120,20 @@ static int tids_auth_connection (int conn, gss_ctx_id_t *gssctx) int auth, autherr = 0; if (rc = gsscon_passive_authenticate(conn, gssctx)) { - fprintf(stderr, "Error from gsscon_passive_authenticate(), rc = %d.\n", rc); + fprintf(stderr, "tids_auth_connection: 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", + fprintf(stderr, "tids_auth_connection: Error from gsscon_authorize, rc = %d, autherr = %d.\n", rc, autherr); return -1; } if (auth) - fprintf(stdout, "Connection authenticated, conn = %d.\n", conn); + fprintf(stdout, "tids_auth_connection: Connection authenticated, conn = %d.\n", conn); else - fprintf(stderr, "Authentication failed, conn %d.\n", conn); + fprintf(stderr, "tids_auth_connection: Authentication failed, conn %d.\n", conn); return !auth; } @@ -112,14 +154,14 @@ static int tids_read_request (TIDS_INSTANCE *tids, int conn, gss_ctx_id_t *gssct /* Parse request */ if (NULL == ((*mreq) = tr_msg_decode(buf, buflen))) { - printf("tids_read_request():Error decoding request.\n"); + fprintf(stderr, "tids_read_request():Error decoding request.\n"); free (buf); return -1; } /* If this isn't a TID Request, just drop it. */ if (TID_REQUEST != (*mreq)->msg_type) { - printf("tids_read_request(): Not a TID Request, dropped.\n"); + fprintf(stderr, "tids_read_request(): Not a TID Request, dropped.\n"); return -1; } @@ -136,7 +178,7 @@ static int tids_handle_request (TIDS_INSTANCE *tids, TR_MSG *mreq, TID_RESP **re (!mreq->tid_req->rp_realm) || (!mreq->tid_req->realm) || (!mreq->tid_req->comm)) { - printf("tids_handle_request():Not a valid TID Request.\n"); + fprintf(stderr, "tids_handle_request():Not a valid TID Request.\n"); (*resp)->result = TID_ERROR; (*resp)->err_msg = tr_new_name("Bad request format"); return -1; @@ -153,35 +195,68 @@ static int tids_handle_request (TIDS_INSTANCE *tids, TR_MSG *mreq, TID_RESP **re else { /* set-up a success response */ (*resp)->result = TID_SUCCESS; - (*resp)->err_msg = NULL; /* No msg on successful return */ + (*resp)->err_msg = NULL; /* No error msg on successful return */ } return rc; } -int tids_send_response (TIDS_INSTANCE *tids, int conn, gss_ctx_id_t *gssctx, TID_RESP *resp) +int tids_send_err_response (TIDS_INSTANCE *tids, TID_REQ *req, const char *err_msg) { + TID_RESP *resp = NULL; + int rc = 0; + + /* If we already sent a response, don't send another no matter what. */ + if (req->resp_sent) + return 0; + + if (NULL == (resp = tids_create_response(tids, req))) { + fprintf(stderr, "tids_send_err_response: Can't create response.\n"); + return -1; + } + + /* mark this as an error response, and include the error message */ + resp->result = TID_ERROR; + resp->err_msg = tr_new_name((char *)err_msg); + + rc = tids_send_response(tids, req, resp); + + tids_destroy_response(tids, resp); + return rc; +} + +int tids_send_response (TIDS_INSTANCE *tids, TID_REQ *req, TID_RESP *resp) { int err; TR_MSG mresp; char *resp_buf; + if ((!tids) || (!req) || (!resp)) + fprintf (stderr, "tids_send_response: Invalid parameters.\n"); + + /* Never send a second response if we already sent one. */ + if (req->resp_sent) + return -1; + mresp.msg_type = TID_RESPONSE; mresp.tid_resp = resp; if (NULL == (resp_buf = tr_msg_encode(&mresp))) { - fprintf(stderr, "Error decoding json response.\n"); + fprintf(stderr, "tids_send_response: Error encoding json response.\n"); return -1; } - printf("Encoded response:\n%s\n", resp_buf); + fprintf(stderr, "tids_send_response: Encoded response:\n%s\n", resp_buf); /* Send the response over the connection */ - if (err = gsscon_write_encrypted_token (conn, *gssctx, resp_buf, + if (err = gsscon_write_encrypted_token (req->conn, req->gssctx, resp_buf, strlen(resp_buf) + 1)) { - fprintf(stderr, "Error sending response over connection.\n"); + fprintf(stderr, "tids_send_response: Error sending response over connection.\n"); return -1; } + /* indicate that a response has been sent for this request */ + req->resp_sent = 1; + free(resp_buf); return 0; @@ -195,17 +270,17 @@ static void tids_handle_connection (TIDS_INSTANCE *tids, int conn) gss_ctx_id_t gssctx = GSS_C_NO_CONTEXT; if (tids_auth_connection(conn, &gssctx)) { - fprintf(stderr, "Error authorizing TID Server connection.\n"); + fprintf(stderr, "tids_handle_connection: Error authorizing TID Server connection.\n"); close(conn); return; } - printf("Connection authorized!\n"); + fprintf(stdout, "tids_handle_connection: Connection authorized!\n"); while (1) { /* continue until an error breaks us out */ if (0 > (rc = tids_read_request(tids, conn, &gssctx, &mreq))) { - fprintf(stderr, "Error from tids_read_request(), rc = %d.\n", rc); + fprintf(stderr, "tids_handle_connection: Error from tids_read_request(), rc = %d.\n", rc); return; } else if (0 == rc) { continue; @@ -216,31 +291,29 @@ static void tids_handle_connection (TIDS_INSTANCE *tids, int conn) mreq->tid_req->gssctx = gssctx; /* Allocate a response structure and populate common fields */ - if ((NULL == (resp = calloc(sizeof(TID_RESP), 1)))) { - fprintf(stderr, "Error allocating response structure.\n"); + if (NULL == (resp = tids_create_response (tids, mreq->tid_req))) { + fprintf(stderr, "tids_handle_connection: Error creating response structure.\n"); + /* try to send an error */ + tids_send_err_response(tids, mreq->tid_req, "Error creating response.\n"); return; } - /* TBD -- handle errors */ - 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) - resp->orig_coi = tr_dup_name(mreq->tid_req->orig_coi); - if (0 > (rc = tids_handle_request(tids, mreq, &resp))) { - fprintf(stderr, "Error from tids_handle_request(), rc = %d.\n", rc); - return; + fprintf(stderr, "tids_handle_connection: Error from tids_handle_request(), rc = %d.\n", rc); + /* Fall through, to send the response, either way */ } - if (0 > (rc = tids_send_response(tids, conn, &gssctx, resp))) { - fprintf(stderr, "Error from tids_send_response(), rc = %d.\n", rc); - return; + if (0 > (rc = tids_send_response(tids, mreq->tid_req, resp))) { + fprintf(stderr, "tids_handle_connection: Error from tids_send_response(), rc = %d.\n", rc); + /* if we didn't already send a response, try to send a generic error. */ + if (!mreq->tid_req->resp_sent) + tids_send_err_response(tids, mreq->tid_req, "Error sending response.\n"); + /* Fall through to free the response, either way. */ } - } - - return; + + tids_destroy_response(tids, resp); + return; + } } TIDS_INSTANCE *tids_create (void) @@ -296,7 +369,8 @@ int tids_start (TIDS_INSTANCE *tids, void tids_destroy (TIDS_INSTANCE *tids) { - free(tids); + if (tids) + free(tids); } diff --git a/tr/tr_main.c b/tr/tr_main.c index 49b4eeb..ceb0fb1 100644 --- a/tr/tr_main.c +++ b/tr/tr_main.c @@ -52,11 +52,13 @@ static void tr_tidc_resp_handler (TIDC_INSTANCE *tidc, 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); + fprintf(stderr, "tr_tidc_resp_handler: Response received (conn = %d)! Realm = %s, Community = %s.\n", ((TR_RESP_COOKIE *)resp_cookie)->orig_req->conn, 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); + tids_send_response(((TR_RESP_COOKIE *)resp_cookie)->tr->tids, + ((TR_RESP_COOKIE *)resp_cookie)->orig_req, + resp); return; } @@ -70,73 +72,89 @@ static int tr_tids_req_handler (TIDS_INSTANCE * tids, TR_RESP_COOKIE resp_cookie; TR_AAA_SERVER *aaa_servers = NULL; TR_NAME *apc = NULL; - TID_REQ *req = NULL; + TID_REQ *fwd_req = NULL; TR_COMM *cfg_comm = NULL; int rc; if ((!tids) || (!orig_req) || (!resp) || (!(*resp))) { - printf("tids_req_handler: Bad parameters\n"); + fprintf(stderr, "tids_req_handler: Bad parameters\n"); return -1; } - printf("Request received! Realm = %s, Comm = %s\n", orig_req->realm->buf, orig_req->comm->buf); + fprintf(stdout, "tr_tids_req_handler: Request received (conn = %d)! Realm = %s, Comm = %s\n", orig_req->conn, + orig_req->realm->buf, orig_req->comm->buf); if (tids) tids->req_count++; - /* 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))) { + if (NULL == (fwd_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); + if (NULL == (cfg_comm = tr_comm_lookup((TR_INSTANCE *)tids->cookie, orig_req->comm))) { + fprintf(stderr, "tr_tids_req_hander: Request for unknown comm: %s.\n", orig_req->comm->buf); + tids_send_err_response(tids, orig_req, "Unknown community"); + return -1; } /* TBD -- check that the rp_realm is a member of the original community */ + /* If the community is a COI, switch to the apc */ if (TR_COMM_COI == cfg_comm->type) { + fprintf(stderr, "tr_tids_req_handler: Community was a COI, switching.\n"); /* TBD -- In theory there can be more than one? How would that work? */ + if ((!cfg_comm->apcs) || (!cfg_comm->apcs->id)) { + fprintf(stderr, "No valid APC for COI %s.\n", orig_req->comm->buf); + tids_send_err_response(tids, orig_req, "No valid APC for community"); + return -1; + } apc = tr_dup_name(cfg_comm->apcs->id); - req->orig_coi = req->comm; - req->comm = apc; + fwd_req->comm = apc; + fwd_req->orig_coi = orig_req->comm; } /* Find the AAA server(s) for this request */ - aaa_servers = tr_idp_aaa_server_lookup((TR_INSTANCE *)tids->cookie, req->realm, apc); + if (NULL == (aaa_servers = tr_idp_aaa_server_lookup((TR_INSTANCE *)tids->cookie, + orig_req->realm, + orig_req->comm))) { + fprintf(stderr, "tr_tids_req_handler: No AAA Servers for realm %s.\n", orig_req->realm->buf); + tids_send_err_response(tids, orig_req, "No path to AAA Servers for realm"); + return -1; + } /* 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"); + tids_send_err_response(tids, orig_req, "Memory allocation failure"); return -1; } /* 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; + tidc->client_dh = orig_req->tidc_dh; /* Save information about this request for the response */ resp_cookie.tr = tr; - resp_cookie.orig_req = req; + resp_cookie.orig_req = orig_req; /* Set-up TID connection */ /* 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"); + if (-1 == (fwd_req->conn = tidc_open_connection(tidc, + inet_ntoa(aaa_servers->aaa_server_addr), + &(fwd_req->gssctx)))) { + fprintf(stderr, "tr_tids_req_handler: Error in tidc_open_connection.\n"); + tids_send_err_response(tids, orig_req, "Can't open connection to next hop TIDS"); return -1; }; /* Send a TID request */ - - 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); + if (0 > (rc = tidc_fwd_request(tidc, fwd_req, &tr_tidc_resp_handler, (void *)&resp_cookie))) { + fprintf(stderr, "Error from tidc_fwd_request, rc = %d.\n", rc); + tids_send_err_response(tids, orig_req, "Can't forward request to next hop TIDS"); return -1; } @@ -183,13 +201,13 @@ int main (int argc, const char *argv[]) /* initialize the trust path query server instance */ if (0 == (tr->tids = tids_create ())) { - printf ("Error initializing Trust Path Query Server instance.\n"); + fprintf (stderr, "Error initializing Trust Path Query Server instance.\n"); exit(1); } /* start the trust path query server, won't return unless fatal error. */ if (0 != (err = tids_start(tr->tids, &tr_tids_req_handler, (void *)tr))) { - printf ("Error from Trust Path Query Server, err = %d.\n", err); + fprintf (stderr, "Error from Trust Path Query Server, err = %d.\n", err); exit(err); } -- 2.1.4