X-Git-Url: http://www.project-moonshot.org/gitweb/?p=trust_router.git;a=blobdiff_plain;f=tid%2Ftidc.c;h=90335f0ed6375df3350183c9e59fc0eb001612e4;hp=06ae22039f55e49b620541d6e29b17801e6a988d;hb=3c5fb17459ff56d5e23cea059503f46a42150a1e;hpb=5fd8d12e4c043265a900f5812181cd43cbc4f7c4 diff --git a/tid/tidc.c b/tid/tidc.c index 06ae220..90335f0 100644 --- a/tid/tidc.c +++ b/tid/tidc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, JANET(UK) + * Copyright (c) 2012, 2014-2015, JANET(UK) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,88 +33,91 @@ */ #include -#include #include -#include +#include +#include #include -#include +#include #include -#include +#include +#include + int tmp_len = 32; -TIDC_INSTANCE *tidc_create () +/* creates struct in talloc null context */ +TIDC_INSTANCE *tidc_create(void) { - TIDC_INSTANCE *tidc = NULL; - - if (tidc = malloc(sizeof(TIDC_INSTANCE))) - memset(tidc, 0, sizeof(TIDC_INSTANCE)); - else - return NULL; - + TIDC_INSTANCE *tidc=talloc(NULL, TIDC_INSTANCE); + if (tidc!=NULL) { + tidc->gssc = tr_gssc_instance_new(tidc); + if (tidc->gssc == NULL) { + talloc_free(tidc); + return NULL; + } + + tidc->gssc->service_name = "trustidentity"; + } return tidc; } -void tidc_destroy (TIDC_INSTANCE *tidc) +void tidc_destroy(TIDC_INSTANCE *tidc) { - if (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; + talloc_free(tidc); } int tidc_open_connection (TIDC_INSTANCE *tidc, - char *server, - gss_ctx_id_t *gssctx) + const char *server, + unsigned int port, + gss_ctx_id_t *gssctx) { - int err = 0; - int conn = -1; - - err = gsscon_connect(server, TID_PORT, &conn); + unsigned int use_port = 0; + tidc->gssc->gss_ctx = gssctx; - if (!err) - err = gsscon_active_authenticate(conn, NULL, "trustidentity", gssctx); + if (0 == port) + use_port = TID_PORT; + else + use_port = port; - if (!err) - return conn; + tr_debug("tidc_open_connection: opening tidc connection to %s:%d", server, use_port); + if (0 == tr_gssc_open_connection(tidc->gssc, server, use_port)) + return tidc->gssc->conn; else return -1; } -int tidc_send_request (TIDC_INSTANCE *tidc, - int conn, - gss_ctx_id_t gssctx, - char *rp_realm, - char *realm, - char *comm, - TIDC_RESP_FUNC *resp_handler, - void *cookie) - +int tidc_send_request (TIDC_INSTANCE *tidc, + int conn, + gss_ctx_id_t gssctx, + const char *rp_realm, + const char *realm, + const char *comm, + TIDC_RESP_FUNC *resp_handler, + void *cookie) { TID_REQ *tid_req = NULL; + char *request_id = NULL; + int rc; + int orig_conn = 0; + gss_ctx_id_t *orig_gss_ctx = NULL; + + /* For ABI compatibility, replace the generic GSS client parameters + * with the arguments we were passed. */ + orig_conn = tidc->gssc->conn; /* save to restore later */ + if (conn != tidc->gssc->conn) { + tr_warning("tidc_send_request: WARNING: socket connection FD does not match FD opened by tidc_open_connection()"); + tidc->gssc->conn = conn; + } + orig_gss_ctx = tidc->gssc->gss_ctx; /* save to restore later */ + if (gssctx != *(tidc->gssc->gss_ctx)) { + tr_warning("tidc_send_request: WARNING: sending request with different GSS context than used for tidc_open_connection()"); + *tidc->gssc->gss_ctx = gssctx; + } /* Create and populate a TID req structure */ - if (!(tid_req = malloc(sizeof(TID_REQ)))) - return -1; - - memset(tid_req, 0, sizeof(tid_req)); + if (!(tid_req = tid_req_new())) + goto error; tid_req->conn = conn; tid_req->gssctx = gssctx; @@ -122,96 +125,106 @@ int tidc_send_request (TIDC_INSTANCE *tidc, 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; + tr_err ( "tidc_send_request: Error duplicating names.\n"); + goto error; } - 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)); -} + tid_req->tidc_dh = tr_dh_dup(tidc->gssc->client_dh); + + /* generate an ID */ + request_id = tr_random_id(NULL); + if (request_id) { + if (tid_req->request_id = tr_new_name(request_id)) + tr_debug("tidc_send_request: Created TID request ID: %s", request_id); + else + tr_debug("tidc_send_request: Unable to set request ID, proceeding without one"); + talloc_free(request_id); + } else + tr_debug("tidc_send_request: Failed to generate a TID request ID, proceeding without one"); + + rc = tidc_fwd_request(tidc, tid_req, resp_handler, cookie); + goto cleanup; + error: + rc = -1; + cleanup: + if (tid_req) + tid_req_free(tid_req); -int tidc_fwd_request (TIDC_INSTANCE *tidc, - TID_REQ *tid_req, - TIDC_RESP_FUNC *resp_handler, - void *cookie) + tidc->gssc->conn = orig_conn; + tidc->gssc->gss_ctx = orig_gss_ctx; + return rc; +} +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; + TALLOC_CTX *tmp_ctx = talloc_new(NULL); TR_MSG *msg = NULL; TR_MSG *resp_msg = NULL; - int err; + TID_RESP *tid_resp = NULL; + int rc = 0; /* Create and populate a TID msg structure */ - if (!(msg = malloc(sizeof(TR_MSG)))) - return -1; + if (!(msg = talloc_zero(tmp_ctx, TR_MSG))) + goto error; msg->msg_type = TID_REQUEST; - msg->tid_req = tid_req; + tr_msg_set_req(msg, tid_req); - /* Encode the request into a json string */ - if (!(req_buf = tr_msg_encode(msg))) { - printf("Error encoding TID request.\n"); - return -1; - } - printf ("Sending TID request:\n"); - printf ("%s\n", req_buf); + tr_debug( "tidc_fwd_request: Sending TID request\n"); /* 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"); - return -1; - } - - /* TBD -- queue request on instance, read resps in separate thread */ + resp_msg = tr_gssc_exchange_msgs(tmp_ctx, tidc->gssc, msg); + if (resp_msg == NULL) + goto error; - /* 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; + /* TBD -- Check if this is actually a valid response */ + tid_resp = tr_msg_get_resp(resp_msg); + if (tid_resp == NULL) { + tr_err( "tidc_fwd_request: Error, no response in the response!\n"); + goto error; } - fprintf(stdout, "Response Received (%d bytes).\n", 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"); - return -1; + /* Check whether the request IDs matched and warn if not. Do nothing if we don't get + * an ID on the return - it is not mandatory to preserve that field. */ + if (tid_req->request_id) { + if ((tid_resp->request_id) + && (tr_name_cmp(tid_resp->request_id, tid_req->request_id) != 0)) { + /* Requests present but do not match */ + tr_warning("tidc_fwd_request: Sent request ID %.*s, received response for %.*s", + tid_req->request_id->len, tid_req->request_id->buf, + tid_resp->request_id->len, tid_resp->request_id->buf); + } + } else if (tid_resp->request_id) { + tr_warning("tidc_fwd_request: Sent request without ID, received response for %.*s", + tid_resp->request_id->len, tid_resp->request_id->buf); } - /* TBD -- Check if this is actually a valid response */ - if (!resp_msg->tid_resp) { - fprintf(stderr, "Error: No response in the response!\n"); - return -1; + if (resp_handler) { + /* Call the caller's response function. It must copy any data it needs before returning. */ + tr_debug("tidc_fwd_request: calling response callback function."); + (*resp_handler)(tidc, tid_req, tr_msg_get_resp(resp_msg), cookie); } - - /* Call the caller's response function */ - (*tid_req->resp_func)(tidc, tid_req, resp_msg->tid_resp, cookie); - - if (msg) - free(msg); - if (tid_req) - free(tid_req); - if (req_buf) - free(req_buf); - if (resp_buf) - free(resp_buf); - - /* TBD -- free the decoded response */ + goto cleanup; - return 0; + error: + rc = -1; + cleanup: + talloc_free(tmp_ctx); + return rc; } +DH * tidc_get_dh(TIDC_INSTANCE *inst) +{ + return tr_gssc_get_dh(inst->gssc); +} - - +DH *tidc_set_dh(TIDC_INSTANCE *inst, DH *dh) +{ + return tr_gssc_set_dh(inst->gssc, dh); +}