X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=tid%2Ftidc.c;h=1cff6f0b64a09b852c407a8db596b3b0a2863548;hb=6e759de84152b3a9390d009ce9adbd06354dd69e;hp=bb97ebd894a721bfb13ceb7d594bb7c206318fbd;hpb=d7acd9d8f761bfd4a62715de635b1f90234dabfa;p=trust_router.git diff --git a/tid/tidc.c b/tid/tidc.c index bb97ebd..1cff6f0 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,155 +33,211 @@ */ #include -#include #include +#include #include -#include -#include +#include +#include #include -#include +#include +#include -/* char tmp_key[32] = - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x19, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; -*/ int tmp_len = 32; -TIDC_INSTANCE *tidc_create () +static int tidc_destructor(void *obj) { - TIDC_INSTANCE *tidc = NULL; - - if (tidc = malloc(sizeof(TIDC_INSTANCE))) - memset(tidc, 0, sizeof(TIDC_INSTANCE)); - else - return NULL; - - if (NULL == (tidc->priv_dh = tr_create_dh_params(NULL, 0))) { - free (tidc); - return NULL; + TIDC_INSTANCE *tidc=talloc_get_type_abort(obj, TIDC_INSTANCE); + if (NULL!=tidc) { + if (NULL!=tidc->client_dh) + tr_destroy_dh_params(tidc->client_dh); } + return 0; +} - fprintf(stderr, "TIDC DH Parameters:\n"); - DHparams_print_fp(stdout, tidc->priv_dh); - fprintf(stderr, "\n"); +/* creates struct in talloc null context */ +TIDC_INSTANCE *tidc_create(void) +{ + 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"; + tidc->client_dh = NULL; + talloc_set_destructor((void *)tidc, tidc_destructor); + } return tidc; } -void tidc_destroy (TIDC_INSTANCE *tidc) +void tidc_destroy(TIDC_INSTANCE *tidc) { - if (tidc) - free(tidc); + 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, "trustquery", 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) { - json_t *jreq; - int err; - char *req_buf; - char *resp_buf; - size_t resp_buflen = 0; - TR_MSG *msg; - TID_REQ *tid_req; + 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 msg structure */ - if ((!(msg = malloc(sizeof(TR_MSG)))) || - (!(tid_req = malloc(sizeof(TID_REQ))))) - return -1; + /* Create and populate a TID req structure */ + if (!(tid_req = tid_req_new())) + goto error; - memset(tid_req, 0, sizeof(tid_req)); + tid_req->conn = conn; + tid_req->gssctx = gssctx; - msg->msg_type = TID_REQUEST; + 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)))) { + tr_err ( "tidc_send_request: Error duplicating names.\n"); + goto error; + } - msg->tid_req = tid_req; + tid_req->tidc_dh = tr_dh_dup(tidc_get_dh(tidc)); + + /* 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); - tid_req->conn = conn; + tidc->gssc->conn = orig_conn; + tidc->gssc->gss_ctx = orig_gss_ctx; + return rc; +} - /* 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); +int tidc_fwd_request(TIDC_INSTANCE *tidc, + TID_REQ *tid_req, + TIDC_RESP_FUNC *resp_handler, + void *cookie) +{ + TALLOC_CTX *tmp_ctx = talloc_new(NULL); + TR_MSG *msg = NULL; + TR_MSG *resp_msg = NULL; + TID_RESP *tid_resp = NULL; + int rc = 0; - tid_req->tidc_dh = tidc->priv_dh; - - tid_req->resp_func = resp_handler; - tid_req->cookie = cookie; + /* Create and populate a TID msg structure */ + if (!(msg = talloc_zero(tmp_ctx, TR_MSG))) + goto error; - /* Encode the request into a json string */ - if (!(req_buf = tr_msg_encode(msg))) { - printf("Error encoding TID request.\n"); - return -1; - } + msg->msg_type = TID_REQUEST; + tr_msg_set_req(msg, tid_req); - 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 (conn, gssctx, req_buf, - strlen(req_buf))) { - fprintf(stderr, "Error sending request over connection.\n"); - return -1; + resp_msg = tr_gssc_exchange_msgs(tmp_ctx, tidc->gssc, msg); + if (resp_msg == NULL) + goto error; + + /* 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; } - /* TBD -- should queue request on instance, resps read in separate thread */ - /* 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; + /* 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); } - fprintf(stdout, "Response Received, %d bytes.\n", resp_buflen); - - /* Parse response -- TBD */ - - /* Call the caller's response function */ - (*resp_handler)(tidc, NULL, cookie); + 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); + } - if (msg) - free(msg); - if (tid_req) - free(tid_req); - if (req_buf) - free(req_buf); - if (resp_buf) - free(resp_buf); + goto cleanup; - return 0; + error: + rc = -1; + cleanup: + talloc_free(tmp_ctx); + return rc; } +DH *tidc_get_dh(TIDC_INSTANCE *inst) +{ + return inst->client_dh; +} - - +DH *tidc_set_dh(TIDC_INSTANCE *inst, DH *dh) +{ + inst->client_dh = dh; + return dh; +}