X-Git-Url: http://www.project-moonshot.org/gitweb/?p=trust_router.git;a=blobdiff_plain;f=tid%2Ftidc.c;h=90335f0ed6375df3350183c9e59fc0eb001612e4;hp=e7ab9775b182a339ce7d1c57b069b95fa91d979e;hb=3c5fb17459ff56d5e23cea059503f46a42150a1e;hpb=462cb7735160702872dc2be52b8391a459d2b37c diff --git a/tid/tidc.c b/tid/tidc.c index e7ab977..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,154 +33,198 @@ */ #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; -TPQC_INSTANCE *tpqc_create () +/* creates struct in talloc null context */ +TIDC_INSTANCE *tidc_create(void) { - TPQC_INSTANCE *tpqc = NULL; - - if (tpqc = malloc(sizeof(TPQC_INSTANCE))) - memset(tpqc, 0, sizeof(TPQC_INSTANCE)); - else - return NULL; - - if (NULL == (tpqc->priv_dh = tr_create_dh_params(NULL, 0))) { - free (tpqc); - 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"; } - - fprintf(stderr, "TPQC DH Parameters:\n"); - DHparams_print_fp(stdout, tpqc->priv_dh); - fprintf(stderr, "\n"); - - return tpqc; + return tidc; } -void tpqc_destroy (TPQC_INSTANCE *tpqc) +void tidc_destroy(TIDC_INSTANCE *tidc) { - if (tpqc) - free(tpqc); + talloc_free(tidc); } -int tpqc_open_connection (TPQC_INSTANCE *tpqc, - char *server, - gss_ctx_id_t *gssctx) +int tidc_open_connection (TIDC_INSTANCE *tidc, + const char *server, + unsigned int port, + gss_ctx_id_t *gssctx) { - int err = 0; - int conn = -1; - - err = gsscon_connect(server, TPQ_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 tpqc_send_request (TPQC_INSTANCE *tpqc, - int conn, - gss_ctx_id_t gssctx, - char *rp_realm, - char *realm, - char *coi, - TPQC_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; - TPQ_REQ *tpq_req; - - /* Create and populate a TPQ msg structure */ - if ((!(msg = malloc(sizeof(TR_MSG)))) || - (!(tpq_req = malloc(sizeof(TPQ_REQ))))) - return -1; + 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; + } - memset(tpq_req, 0, sizeof(tpq_req)); + /* Create and populate a TID req structure */ + if (!(tid_req = tid_req_new())) + goto error; - msg->msg_type = TPQ_REQUEST; + tid_req->conn = conn; + tid_req->gssctx = gssctx; - msg->tpq_req = tpq_req; + 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; + } - tpq_req->conn = conn; + 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); + + tidc->gssc->conn = orig_conn; + tidc->gssc->gss_ctx = orig_gss_ctx; + return rc; +} - /* TBD -- error handling */ - tpq_req->rp_realm = tr_new_name(rp_realm); - tpq_req->realm = tr_new_name(realm); - tpq_req->coi = tr_new_name(coi); +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; - tpq_req->tpqc_dh = tpqc->priv_dh; - - tpq_req->resp_func = resp_handler; - tpq_req->cookie = cookie; + /* Create and populate a TID msg structure */ + if (!(msg = talloc_zero(tmp_ctx, TR_MSG))) + goto error; + + msg->msg_type = TID_REQUEST; + tr_msg_set_req(msg, tid_req); - /* Encode the request into a json string */ - if (!(req_buf = tr_msg_encode(msg))) { - printf("Error encoding TPQ request.\n"); - return -1; - } - printf ("Sending TPQ 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)(tpqc, 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 (tpq_req) - free(tpq_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 tr_gssc_get_dh(inst->gssc); +} - - +DH *tidc_set_dh(TIDC_INSTANCE *inst, DH *dh) +{ + return tr_gssc_set_dh(inst->gssc, dh); +}