From 5831eccf8362e9323b0e353d400d70c4ecb80883 Mon Sep 17 00:00:00 2001 From: Margaret Wasserman Date: Mon, 25 Mar 2013 19:07:57 -0400 Subject: [PATCH] Fixed warnings, fixed bugs in key generation code. --- common/dh_test/dh_test.c | 11 ++- common/tr_dh.c | 17 ++-- common/tr_msg.c | 221 +++++++++++++++++++++++++++++++++------------ include/tr_dh.h | 9 +- include/trust_router/tid.h | 56 +++++++----- tid/example/tidc_main.c | 9 +- tid/example/tids_main.c | 71 +++++++++++++-- tid/tidc.c | 65 +++++++++++-- tid/tids.c | 131 ++++++++++++++++++--------- tr/tr_main.c | 10 +- 10 files changed, 431 insertions(+), 169 deletions(-) diff --git a/common/dh_test/dh_test.c b/common/dh_test/dh_test.c index 394db38..a0d0a3d 100644 --- a/common/dh_test/dh_test.c +++ b/common/dh_test/dh_test.c @@ -34,6 +34,7 @@ #include #include +#include #include @@ -56,9 +57,9 @@ int main (int argc, { DH *c_dh = NULL; DH *s_dh = NULL; - char *c_keybuf = NULL; - char *s_keybuf = NULL; - int dh_err = 0, c_keylen = 0, s_keylen = 0, i = 0; + unsigned char *c_keybuf = NULL; + unsigned char *s_keybuf = NULL; + int c_keylen = 0, s_keylen = 0, i = 0; /* TBD -- Generate random private keys */ @@ -114,14 +115,14 @@ int main (int argc, /* Print out the client key. */ printf("Client Key Generated (len = %d):\n", c_keylen); for (i = 0; i < c_keylen; i++) { - printf("%x", c_keybuf[i]); + printf("%2x", c_keybuf[i]); } printf("\n"); /* Print out the server key. */ printf("Server Key Generated (len = %d):\n", s_keylen); for (i = 0; i < s_keylen; i++) { - printf("%x", s_keybuf[i]); + printf("%2x", s_keybuf[i]); } printf("\n"); diff --git a/common/tr_dh.c b/common/tr_dh.c index ab3a7a4..ec887db 100644 --- a/common/tr_dh.c +++ b/common/tr_dh.c @@ -70,7 +70,7 @@ unsigned char tr_2048_dhprime[2048/8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -DH *tr_create_dh_params(char *priv_key, +DH *tr_create_dh_params(unsigned char *priv_key, size_t keylen) { DH *dh = NULL; @@ -112,7 +112,7 @@ DH *tr_create_dh_params(char *priv_key, return(dh); } -DH *tr_create_matching_dh (char *priv_key, +DH *tr_create_matching_dh (unsigned char *priv_key, size_t keylen, DH *in_dh) { DH *dh = NULL; @@ -121,13 +121,16 @@ DH *tr_create_matching_dh (char *priv_key, if (!in_dh) return NULL; - if (NULL == (dh = DH_new())) + if (NULL == (dh = DH_new())) { + fprintf(stderr, "Unable to allocate new DH structure.\n"); return NULL; + } if ((NULL == (dh->g = BN_dup(in_dh->g))) || - (NULL == (dh->p = BN_dup(in_dh->p))) || - (NULL == (dh->q = BN_dup(in_dh->q)))) { + (NULL == (dh->p = BN_dup(in_dh->p)))) { DH_free(dh); + fprintf(stderr, "Invalid dh parameter values, can't be duped.\n"); + return NULL; } /* TBD -- share code with previous function */ @@ -170,8 +173,10 @@ int tr_compute_dh_key(unsigned char *buf, if ((!buf) || (!pub_key) || (!priv_dh) || - (buflen < DH_size(priv_dh))) + (buflen < DH_size(priv_dh))) { + fprintf(stderr, "tr_compute_dh_key(): Invalid parameters.\n"); return(-1); + } rc = DH_compute_key(buf, pub_key, priv_dh); return rc; diff --git a/common/tr_msg.c b/common/tr_msg.c index 0554d5a..914868d 100644 --- a/common/tr_msg.c +++ b/common/tr_msg.c @@ -31,7 +31,9 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. * */ - +#include +#include +#include #include #include #include @@ -65,11 +67,9 @@ static json_t *tr_msg_encode_dh(DH *dh) static DH *tr_msg_decode_dh(json_t *jdh) { DH *dh = NULL; - json_error_t rc; json_t *jp = NULL; json_t *jg = NULL; json_t *jpub_key = NULL; - int msize; if (!(dh = malloc(sizeof(DH)))) { fprintf (stderr, "tr_msg_decode_dh(): Error allocating DH structure.\n"); @@ -79,14 +79,10 @@ static DH *tr_msg_decode_dh(json_t *jdh) memset(dh, 0, sizeof(DH)); /* store required fields from dh object */ - if (((msize = json_object_size(jdh)) < 3) || - (NULL == (jp = json_object_get(jdh, "dh_p"))) || - (!json_is_string(jp)) || + if ((NULL == (jp = json_object_get(jdh, "dh_p"))) || (NULL == (jg = json_object_get(jdh, "dh_g"))) || - (!json_is_string(jg)) || - (NULL == (jpub_key = json_object_get(jdh, "dh_pub_key"))) || - (!json_is_string(jdh))) { - fprintf (stderr, "tr_msg_decode(): Error parsing message.\n"); + (NULL == (jpub_key = json_object_get(jdh, "dh_pub_key")))) { + fprintf (stderr, "tr_msg_decode_dh(): Error parsing dh_info.\n"); free(dh); return NULL; } @@ -125,13 +121,11 @@ static json_t * tr_msg_encode_tidreq(TID_REQ *req) static TID_REQ *tr_msg_decode_tidreq(json_t *jreq) { TID_REQ *treq = NULL; - json_error_t rc; json_t *jrp_realm = NULL; json_t *jrealm = NULL; json_t *jcomm = NULL; json_t *jorig_coi = NULL; json_t *jdh = NULL; - int msize; if (!(treq = malloc(sizeof(TID_REQ)))) { fprintf (stderr, "tr_msg_decode_tidreq(): Error allocating TID_REQ structure.\n"); @@ -141,16 +135,10 @@ static TID_REQ *tr_msg_decode_tidreq(json_t *jreq) memset(treq, 0, sizeof(TID_REQ)); /* store required fields from request */ - if (((msize = json_object_size(jreq)) < 4) || - (NULL == (jrp_realm = json_object_get(jreq, "rp_realm"))) || - (!json_is_string(jrp_realm)) || - (NULL == (jrealm = json_object_get(jreq, "realm"))) || - (!json_is_string(jrealm)) || - (NULL == (jcomm = json_object_get(jreq, "comm"))) || - (!json_is_string(jcomm)) || - (NULL == (jdh = json_object_get(jreq, "dh_info"))) || - (!json_is_object(jdh))) { - fprintf (stderr, "tr_msg_decode(): Error parsing message.\n"); + if ((NULL == (jrp_realm = json_object_get(jreq, "rp_realm"))) || + (NULL == (jrealm = json_object_get(jreq, "target_realm"))) || + (NULL == (jcomm = json_object_get(jreq, "community")))) { + fprintf (stderr, "tr_msg_decode(): Error parsing required fields.\n"); free(treq); return NULL; } @@ -158,29 +146,146 @@ static TID_REQ *tr_msg_decode_tidreq(json_t *jreq) treq->rp_realm = tr_new_name((char *)json_string_value(jrp_realm)); treq->realm = tr_new_name((char *)json_string_value(jrealm)); treq->comm = tr_new_name((char *)json_string_value(jcomm)); + + /* Get DH Info from the request */ + if (NULL == (jdh = json_object_get(jreq, "dh_info"))) { + fprintf (stderr, "tr_msg_decode(): Error parsing dh_info.\n"); + free(treq); + return NULL; + } treq->tidc_dh = tr_msg_decode_dh(jdh); /* store optional "orig_coi" field */ - if ((NULL != (jorig_coi = json_object_get(jreq, "orig_coi"))) && - (!json_is_object(jorig_coi))) { + if (NULL != (jorig_coi = json_object_get(jreq, "orig_coi"))) { treq->orig_coi = tr_new_name((char *)json_string_value(jorig_coi)); } return treq; } +static json_t *tr_msg_encode_one_server(TID_SRVR_BLK *srvr) +{ + json_t *jsrvr = NULL; + json_t *jstr = NULL; + + fprintf(stderr, "Encoding one server.\n"); + + jsrvr = json_object(); + + /* Server IP Address -- TBD */ + jstr = json_string("127.0.0.1"); + json_object_set_new(jsrvr, "server_addr", jstr); + + /* Server DH Block */ + json_object_set_new(jsrvr, "server_dh", tr_msg_encode_dh(srvr->aaa_server_dh)); + + // fprintf(stderr,"tr_msg_encode_one_server(): jsrvr contains:\n"); + // fprintf(stderr,"%s\n", json_dumps(jsrvr, 0)); + return jsrvr; +} + +static TID_SRVR_BLK *tr_msg_decode_one_server(json_t *jsrvr) +{ + TID_SRVR_BLK *srvr; + json_t *jsrvr_addr = NULL; + json_t *jsrvr_dh = NULL; + + if (jsrvr == NULL) + return NULL; + + if (NULL == (srvr = malloc(sizeof(TID_SRVR_BLK)))) + return NULL; + + if ((NULL == (jsrvr_addr = json_object_get(jsrvr, "server_addr"))) || + (NULL == (jsrvr_dh = json_object_get(jsrvr, "server_dh")))) { + fprintf (stderr, "tr_msg_decode_one_server(): Error parsing required fields.\n"); + free(srvr); + return NULL; + } + + /* TBD -- handle IPv6 Addresses */ + inet_aton(json_string_value(jsrvr_addr), &(srvr->aaa_server_addr)); + srvr->aaa_server_dh = tr_msg_decode_dh(jsrvr_dh); + + return srvr; +} + +static json_t *tr_msg_encode_servers(TID_SRVR_BLK *servers) +{ + json_t *jservers = NULL; + json_t *jsrvr = NULL; + TID_SRVR_BLK *srvr = NULL; + + jservers = json_array(); + + for (srvr = servers; srvr != NULL; srvr = srvr->next) { + if ((NULL == (jsrvr = tr_msg_encode_one_server(srvr))) || + (-1 == json_array_append_new(jservers, jsrvr))) { + return NULL; + } + } + + // fprintf(stderr,"tr_msg_encode_servers(): servers contains:\n"); + // fprintf(stderr,"%s\n", json_dumps(jservers, 0)); + return jservers; +} + +static TID_SRVR_BLK *tr_msg_decode_servers(json_t *jservers) +{ + TID_SRVR_BLK *servers = NULL; + TID_SRVR_BLK *next = NULL; + TID_SRVR_BLK *srvr = NULL; + json_t *jsrvr; + size_t i, num_servers; + + num_servers = json_array_size(jservers); + fprintf(stderr, "tr_msg_decode_servers(): Number of servers = %d.\n", num_servers); + + if (0 == num_servers) { + fprintf(stderr, "tr_msg_decode_servers(): Server array is empty.\n"); + return NULL; + } + + for (i = 0; i < num_servers; i++) { + jsrvr = json_array_get(jservers, i); + srvr = tr_msg_decode_one_server(jsrvr); + + /* skip to the end of the list, and add srvr to list of servers */ + if (NULL == servers) { + servers = srvr; + } + else { + for (next = servers; next->next != NULL; next = next->next); + next->next = srvr; + } + } + + return servers; +} + static json_t * tr_msg_encode_tidresp(TID_RESP *resp) { json_t *jresp = NULL; json_t *jstr = NULL; + json_t *jservers = NULL; - if ((!resp) || (!resp->result) || (!resp->rp_realm) || (!resp->realm) || !(resp->comm)) + if ((!resp) || (!resp->rp_realm) || (!resp->realm) || !(resp->comm)) return NULL; jresp = json_object(); - jstr = json_string(resp->result->buf); - json_object_set_new(jresp, "result", jstr); + if (TID_ERROR == resp->result) { + jstr = json_string("error"); + json_object_set_new(jresp, "result", jstr); + if (resp->err_msg) { + jstr = json_string(resp->err_msg->buf); + json_object_set_new(jresp, "err_msg", jstr); + } + } + else { + jstr = json_string("success"); + json_object_set_new(jresp, "result", jstr); + } jstr = json_string(resp->rp_realm->buf); json_object_set_new(jresp, "rp_realm", jstr); @@ -196,7 +301,12 @@ static json_t * tr_msg_encode_tidresp(TID_RESP *resp) json_object_set_new(jresp, "orig_coi", jstr); } - // TBD -- Encode server info. + if (NULL == resp->servers) { + fprintf(stderr, "tr_msg_encode_tidresp(): No servers to encode.\n"); + return jresp; + } + jservers = tr_msg_encode_servers(resp->servers); + json_object_set_new(jresp, "servers", jservers); return jresp; } @@ -204,14 +314,13 @@ static json_t * tr_msg_encode_tidresp(TID_RESP *resp) static TID_RESP *tr_msg_decode_tidresp(json_t *jresp) { TID_RESP *tresp = NULL; - json_error_t rc; json_t *jresult = NULL; + json_t *jerr_msg = NULL; json_t *jrp_realm = NULL; json_t *jrealm = NULL; json_t *jcomm = NULL; json_t *jorig_coi = NULL; json_t *jservers = NULL; - int msize; if (!(tresp = malloc(sizeof(TID_RESP)))) { fprintf (stderr, "tr_msg_decode_tidresp(): Error allocating TID_RESP structure.\n"); @@ -221,23 +330,28 @@ static TID_RESP *tr_msg_decode_tidresp(json_t *jresp) memset(tresp, 0, sizeof(TID_RESP)); /* store required fields from request */ - if (((msize = json_object_size(jresp)) < 5) || - (NULL == (jresult = json_object_get(jresp, "result"))) || - (!json_is_string(jresult)) || + if ((NULL == (jresult = json_object_get(jresp, "result"))) || (NULL == (jrp_realm = json_object_get(jresp, "rp_realm"))) || - (!json_is_string(jrp_realm)) || - (NULL == (jrealm = json_object_get(jresp, "realm"))) || - (!json_is_string(jrealm)) || + (NULL == (jrealm = json_object_get(jresp, "target_realm"))) || (NULL == (jcomm = json_object_get(jresp, "comm"))) || - (!json_is_string(jcomm)) || - (NULL == (jservers = json_object_get(jresp, "servers"))) || - (!json_is_object(jservers))) { - fprintf (stderr, "tr_msg_decode(): Error parsing message.\n"); + (NULL == (jservers = json_object_get(jresp, "servers")))) { + fprintf (stderr, "tr_msg_decode_tidresp(): Error parsing response.\n"); free(tresp); return NULL; } - tresp->result = tr_new_name((char *)json_string_value(jresult)); + if (0 == (strcmp(json_string_value(jresult), "success"))) { + fprintf(stderr, "tr_msg_decode_tidresp(): Success! result = %s.\n", json_string_value(jresult)); + tresp->result = TID_SUCCESS; + } + else { + tresp->result = TID_ERROR; + fprintf(stderr, "tr_msg_decode_tidresp(): Error! result = %s.\n", json_string_value(jresult)); + if (NULL != (jerr_msg = json_object_get(jresp, "err_msg"))) { + tresp->err_msg = tr_new_name((char *)json_string_value(jerr_msg)); + } + } + tresp->rp_realm = tr_new_name((char *)json_string_value(jrp_realm)); tresp->realm = tr_new_name((char *)json_string_value(jrealm)); tresp->comm = tr_new_name((char *)json_string_value(jcomm)); @@ -248,8 +362,7 @@ static TID_RESP *tr_msg_decode_tidresp(json_t *jresp) tresp->orig_coi = tr_new_name((char *)json_string_value(jorig_coi)); } - // Decode server info - // tresp->servers = tr_msg_decode_servers(jservers); + tresp->servers = tr_msg_decode_servers(jservers); return tresp; } @@ -265,13 +378,13 @@ char *tr_msg_encode(TR_MSG *msg) switch (msg->msg_type) { case TID_REQUEST: - jmsg_type = json_string("TIDRequest"); + jmsg_type = json_string("tid_request"); json_object_set_new(jmsg, "msg_type", jmsg_type); json_object_set_new(jmsg, "msg_body", tr_msg_encode_tidreq(msg->tid_req)); break; case TID_RESPONSE: - jmsg_type = json_string("TIDResponse"); + jmsg_type = json_string("tid_response"); json_object_set_new(jmsg, "msg_type", jmsg_type); json_object_set_new(jmsg, "msg_body", tr_msg_encode_tidresp(msg->tid_resp)); break; @@ -291,13 +404,12 @@ TR_MSG *tr_msg_decode(char *jbuf, size_t buflen) TR_MSG *msg; json_t *jmsg = NULL; json_error_t rc; - size_t msize; json_t *jtype; json_t *jbody; const char *mtype = NULL; - if (NULL == (jmsg = json_loadb(jbuf, buflen, 0, &rc))) { - fprintf (stderr, "tr_msg_decode(): error loading object, rc = %d.\n", rc); + if (NULL == (jmsg = json_loadb(jbuf, buflen, JSON_DISABLE_EOF_CHECK, &rc))) { + fprintf (stderr, "tr_msg_decode(): error loading object\n"); return NULL; } @@ -309,12 +421,9 @@ TR_MSG *tr_msg_decode(char *jbuf, size_t buflen) memset(msg, 0, sizeof(TR_MSG)); - if ((2 != (msize = json_object_size(jmsg))) || - (NULL == (jtype = json_object_get(jmsg, "msg_type"))) || - (!json_is_string(jtype)) || - (NULL == (jbody = json_object_get(jmsg, "msg_body"))) || - (!json_is_object(jbody))) { - fprintf (stderr, "tr_msg_decode(): Error parsing message.\n"); + if ((NULL == (jtype = json_object_get(jmsg, "msg_type"))) || + (NULL == (jbody = json_object_get(jmsg, "msg_body")))) { + fprintf (stderr, "tr_msg_decode(): Error parsing message header.\n"); json_decref(jmsg); tr_msg_free_decoded(msg); return NULL; @@ -322,11 +431,11 @@ TR_MSG *tr_msg_decode(char *jbuf, size_t buflen) mtype = json_string_value(jtype); - if (0 == strcmp(mtype, "TIDRequest")) { + if (0 == strcmp(mtype, "tid_request")) { msg->msg_type = TID_REQUEST; msg->tid_req = tr_msg_decode_tidreq(jbody); } - else if (0 == strcmp(mtype, "TIDResponse")) { + else if (0 == strcmp(mtype, "tid_response")) { msg->msg_type = TID_RESPONSE; msg->tid_resp = tr_msg_decode_tidresp(jbody); } diff --git a/include/tr_dh.h b/include/tr_dh.h index b027e83..a81f64c 100644 --- a/include/tr_dh.h +++ b/include/tr_dh.h @@ -37,10 +37,11 @@ #include #include +#include -DH *tr_create_dh_params(char *key, size_t len); -DH *tr_create_matching_dh(char *key, size_t len, DH *in_dh); -void tr_destroy_dh_params(DH *dh); -int tr_compute_dh_key(unsigned char *buf, size_t buflen, BIGNUM *pub_key, DH *priv_dh); +TR_EXPORT DH *tr_create_dh_params(unsigned char *key, size_t len); +TR_EXPORT DH *tr_create_matching_dh(unsigned char *key, size_t len, DH *in_dh); +TR_EXPORT void tr_destroy_dh_params(DH *dh); +TR_EXPORT int tr_compute_dh_key(unsigned char *buf, size_t buflen, BIGNUM *pub_key, DH *priv_dh); #endif diff --git a/include/trust_router/tid.h b/include/trust_router/tid.h index 2c37e18..0273268 100644 --- a/include/trust_router/tid.h +++ b/include/trust_router/tid.h @@ -45,27 +45,22 @@ typedef struct gss_ctx_id_struct *gss_ctx_id_t; -typedef struct tid_req { - struct tid_req *next_req; - int conn; - TR_NAME *rp_realm; - TR_NAME *realm; - TR_NAME *comm; - TR_NAME *orig_coi; - DH *tidc_dh; /* Client's public dh information */ - void *resp_func; - void *cookie; -} TID_REQ; +typedef struct tid_req TID_REQ; + +typedef enum tid_rc { + TID_SUCCESS = 0, + TID_ERROR +} TID_RC; typedef struct tid_srvr_blk { struct tid_srvr_blk *next; - in_addr_t aaa_server_addr; + struct in_addr aaa_server_addr; DH *aaa_server_dh; /* AAA server's public dh information */ } TID_SRVR_BLK; - typedef struct tid_resp { - TR_NAME *result; + TID_RC result; + TR_NAME *err_msg; TR_NAME *rp_realm; TR_NAME *realm; TR_NAME *comm; @@ -74,22 +69,39 @@ typedef struct tid_resp { /* TBD -- Trust Path Used */ } TID_RESP; -typedef struct tidc_instance { +typedef struct tidc_instance TIDC_INSTANCE; +typedef struct tids_instance TIDS_INSTANCE; +typedef struct tid_req TID_REQ; + +typedef void (TIDC_RESP_FUNC)(TIDC_INSTANCE *, TID_REQ *, TID_RESP *, void *); + +struct tid_req { + struct tid_req *next_req; + int conn; + TR_NAME *rp_realm; + TR_NAME *realm; + TR_NAME *comm; + TR_NAME *orig_coi; + DH *tidc_dh; /* Client's public dh information */ + TIDC_RESP_FUNC *resp_func; + void *cookie; +}; + +struct tidc_instance { TID_REQ *req_list; char *priv_key; int priv_len; DH *priv_dh; /* Client's DH struct with priv and pub keys */ -} TIDC_INSTANCE; +}; -typedef struct tids_instance { +typedef int (TIDS_REQ_FUNC)(TIDS_INSTANCE *, TID_REQ *, TID_RESP **, void *); + +struct tids_instance { int req_count; char *priv_key; - void *req_handler; + TIDS_REQ_FUNC *req_handler; void *cookie; -} TIDS_INSTANCE; - -typedef void (TIDC_RESP_FUNC)(TIDC_INSTANCE *, TID_RESP *, void *); -typedef int (TIDS_REQ_FUNC)(TIDS_INSTANCE *, TID_REQ *, TID_RESP *, void *); +}; TR_EXPORT TIDC_INSTANCE *tidc_create (void); TR_EXPORT int tidc_open_connection (TIDC_INSTANCE *tidc, char *server, gss_ctx_id_t *gssctx); diff --git a/tid/example/tidc_main.c b/tid/example/tidc_main.c index b3da638..d5361ea 100644 --- a/tid/example/tidc_main.c +++ b/tid/example/tidc_main.c @@ -46,13 +46,14 @@ void static tidc_print_usage (const char *name) } static void tidc_resp_handler (TIDC_INSTANCE * tidc, + TID_REQ *req, TID_RESP *resp, void *cookie) { - // printf ("Response received! Realm = %s, COI = %s.\n", resp->realm->buf, - // resp->coi->buf); - printf ("Response received at handler!\n"); + printf ("Response received! Realm = %s, Community = %s.\n", resp->realm->buf, resp->comm->buf); tidc_response_received = 1; + + return; } @@ -60,12 +61,10 @@ int main (int argc, const char *argv[]) { TIDC_INSTANCE *tidc; - TID_REQ *treq; char *server = NULL; char *rp_realm = NULL; char *realm = NULL; char *coi = NULL; - void *cookie = NULL; int conn = 0; int rc; gss_ctx_id_t gssctx; diff --git a/tid/example/tids_main.c b/tid/example/tids_main.c index 26bb10e..be2ab09 100644 --- a/tid/example/tids_main.c +++ b/tid/example/tids_main.c @@ -33,27 +33,80 @@ */ #include +#include #include +#include static int tids_req_handler (TIDS_INSTANCE * tids, TID_REQ *req, - TID_RESP *resp, + TID_RESP **resp, void *cookie) { - printf("Request received! Realm = %s, Comm = %s\n", req->realm->buf, req->comm->buf); + unsigned char *s_keybuf = NULL; + int s_keylen = 0; + int i = 0; + + printf("Request received! target_realm = %s, community = %s\n", req->realm->buf, req->comm->buf); if (tids) tids->req_count++; - if ((NULL == (resp->realm = tr_dup_name(req->realm))) || - (NULL == (resp->comm = tr_dup_name(req->comm)))) { - printf ("Error in tid_dup_name, not responding.\n"); - return 1; + if (!(resp) || !(*resp)) { + printf("tids_req_handler: No response structure.\n"); + return -1; } - return 0; -} + /* Allocate a new server block */ + if (NULL == ((*resp)->servers = malloc(sizeof(TID_SRVR_BLK)))){ + printf("tids_req_handler(): malloc failed.\n"); + return -1; + } + memset((*resp)->servers, 0, sizeof(TID_SRVR_BLK)); + + /* TBD -- Set up the server IP Address */ + + if (!(req) || !(req->tidc_dh)) { + printf("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"); + 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)); + + 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"); + return -1; + } + + /* Generate the server key */ + printf("Generating the server key.\n"); + if (NULL == (s_keybuf = malloc(DH_size((*resp)->servers->aaa_server_dh)))) { + printf ("tids_req_handler(): Can't allocate server keybuf.\n"); + return -1; + } + + if (0 > (s_keylen = tr_compute_dh_key(s_keybuf, + DH_size((*resp)->servers->aaa_server_dh), + req->tidc_dh->pub_key, + (*resp)->servers->aaa_server_dh))) { + printf("tids_req_handler(): Key computation failed."); + return -1; + } + + /* 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]); + } + printf("\n"); + return s_keylen; +} int main (int argc, const char *argv[]) @@ -74,7 +127,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"); + printf("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 4e94990..e0656c7 100644 --- a/tid/tidc.c +++ b/tid/tidc.c @@ -106,13 +106,16 @@ int tidc_send_request (TIDC_INSTANCE *tidc, void *cookie) { - json_t *jreq; - int err; - char *req_buf; - char *resp_buf; + int err = 0; + char *req_buf = NULL; + char *resp_buf = NULL; size_t resp_buflen = 0; - TR_MSG *msg; - TID_REQ *tid_req; + TR_MSG *msg = NULL; + TID_REQ *tid_req = NULL; + TR_MSG *resp_msg = NULL; + int c_keylen = 0; + unsigned char *c_keybuf = NULL; + int i; /* Create and populate a TID msg structure */ if ((!(msg = malloc(sizeof(TR_MSG)))) || @@ -162,12 +165,54 @@ int tidc_send_request (TIDC_INSTANCE *tidc, return -1; } - fprintf(stdout, "Response Received, %u bytes.\n", (unsigned) resp_buflen); + fprintf(stdout, "Response Received (%d bytes).\n", resp_buflen); + fprintf(stdout, "%s\n", resp_buf); - /* Parse response -- TBD */ + if (NULL == (resp_msg = tr_msg_decode(resp_buf, resp_buflen))) { + fprintf(stderr, "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"); + return -1; + } + /* Call the caller's response function */ - (*resp_handler)(tidc, NULL, cookie); + (*tid_req->resp_func)(tidc, tid_req, resp_msg->tid_resp, cookie); + + + /* Generate the client key -- TBD, handle more than one server */ + if (TID_SUCCESS != resp_msg->tid_resp->result) { + fprintf(stderr, "Response is an error.\n"); + return -1; + } + + if (!resp_msg->tid_resp->servers) { + fprintf(stderr, "Response does not contain server info.\n"); + return -1; + } + + if (NULL == (c_keybuf = malloc(DH_size(tid_req->tidc_dh)))) { + fprintf (stderr, "Error: Can't allocate client keybuf, exiting.\n"); + return -1; + } + if (0 > (c_keylen = tr_compute_dh_key(c_keybuf, + DH_size(tid_req->tidc_dh), + resp_msg->tid_resp->servers->aaa_server_dh->pub_key, + tid_req->tidc_dh))) { + + printf("Error computing client key.\n"); + return -1; + } + + /* Print out the client key. */ + printf("Client Key Generated (len = %d):\n", c_keylen); + for (i = 0; i < c_keylen; i++) { + printf("%x", c_keybuf[i]); + } + printf("\n"); if (msg) free(msg); @@ -178,6 +223,8 @@ int tidc_send_request (TIDC_INSTANCE *tidc, if (resp_buf) free(resp_buf); + /* TBD -- free the decoded response */ + return 0; } diff --git a/tid/tids.c b/tid/tids.c index f9d20b2..1eafe6f 100644 --- a/tid/tids.c +++ b/tid/tids.c @@ -41,10 +41,10 @@ #include #include +#include #include - -static int tids_listen (int port) +static int tids_listen (TIDS_INSTANCE *tids, int port) { int rc = 0; int conn = -1; @@ -92,7 +92,7 @@ static int tids_auth_connection (int conn, gss_ctx_id_t *gssctx) return auth; } -static int tids_read_request (int conn, gss_ctx_id_t *gssctx, TID_REQ *req) +static int tids_read_request (TIDS_INSTANCE *tids, int conn, gss_ctx_id_t *gssctx, TR_MSG **mreq) { int err; char *buf; @@ -104,72 +104,88 @@ static int tids_read_request (int conn, gss_ctx_id_t *gssctx, TID_REQ *req) return -1; } - fprintf(stdout, "Request Received, %u bytes.\n", (unsigned) buflen); + fprintf(stdout, "tids_read_request():Request Received, %d bytes.\n", buflen); - /* Parse request -- TBD */ + /* Parse request */ + if (NULL == ((*mreq) = tr_msg_decode(buf, buflen))) { + printf("tids_read_request():Error decoding request.\n"); + free (buf); + return -1; + } - if (buf) - free(buf); + /* 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"); + return -1; + } + free (buf); return buflen; } -static int tids_handle_request (TID_REQ *req, TID_RESP *resp) +static int tids_handle_request (TIDS_INSTANCE *tids, TR_MSG *mreq, TR_MSG **mresp) { - return 0; + int rc; + TID_RESP *resp; + + /* Check that this is a valid TID Request. If not, send an error return. */ + if ((!mreq->tid_req) || + (!mreq->tid_req->rp_realm) || + (!mreq->tid_req->realm) || + (!mreq->tid_req->comm)) { + printf("tids_handle_request():Not a valid TID Request.\n"); + (*mresp)->tid_resp->result = TID_ERROR; + (*mresp)->tid_resp->err_msg = tr_new_name("Bad request format"); + return -1; + } + + /* Call the caller's request handler */ + /* TBD -- Handle different error returns/msgs */ + resp = (*mresp)->tid_resp; + if (0 > (rc = (*tids->req_handler)(tids, mreq->tid_req, &resp, tids->cookie))) { + /* set-up an error response */ + (*mresp)->tid_resp->result = TID_ERROR; + if (!(*mresp)->tid_resp->err_msg) /* Use msg set by handler, if any */ + (*mresp)->tid_resp->err_msg = tr_new_name("Internal processing error"); + } + else { + /* set-up a success response */ + (*mresp)->tid_resp->result = TID_SUCCESS; + (*mresp)->tid_resp->err_msg = NULL; /* No msg on successful return */ + } + + return rc; } -static int tids_send_response (int conn, gss_ctx_id_t *gssctx, TID_RESP *resp) +static int tids_send_response (TIDS_INSTANCE *tids, int conn, gss_ctx_id_t *gssctx, TR_MSG *mresp) { - json_t *jreq; int err; char *resp_buf; - /* Create a json TID response */ - if (NULL == (jreq = json_object())) { - fprintf(stderr,"Error creating json object.\n"); + if (NULL == (resp_buf = tr_msg_encode(mresp))) { + fprintf(stderr, "Error decoding json response.\n"); return -1; } - if (0 > (err = json_object_set_new(jreq, "type", json_string("tid_response")))) { - fprintf(stderr, "Error adding type to response.\n"); - return -1; - } - if (0 > (err = json_object_set_new(jreq, "result", json_string("error")))) { - fprintf(stderr, "Error adding result to response.\n"); - return -1; - } - if (0 > (err = json_object_set_new(jreq, "msg", json_string("No path to realm")))) { - fprintf(stderr, "Error adding msg to response.\n"); - return -1; - } - - /* Encode the json response */ - if (NULL == (resp_buf = json_dumps(jreq, 0))) { - fprintf(stderr, "Error encoding json response.\n"); - return -1; - } - printf("Encoded response:\n%s\n", resp_buf); - /* Send the request over the connection */ + /* Send the response over the connection */ if (err = gsscon_write_encrypted_token (conn, *gssctx, resp_buf, strlen(resp_buf) + 1)) { - fprintf(stderr, "Error sending request over connection.\n"); + fprintf(stderr, "Error sending response over connection.\n"); return -1; } free(resp_buf); return 0; - } -static void tids_handle_connection (int conn) +static void tids_handle_connection (TIDS_INSTANCE *tids, int conn) { - TID_REQ req; - TID_RESP resp; - int rc; + TR_MSG *mreq = NULL; + TR_MSG *mresp = NULL; + int rc = 0; gss_ctx_id_t gssctx = GSS_C_NO_CONTEXT; if (!tids_auth_connection(conn, &gssctx)) { @@ -182,19 +198,37 @@ static void tids_handle_connection (int conn) while (1) { /* continue until an error breaks us out */ - if (0 > (rc = tids_read_request(conn, &gssctx, &req))) { + if (0 > (rc = tids_read_request(tids, conn, &gssctx, &mreq))) { fprintf(stderr, "Error from tids_read_request(), rc = %d.\n", rc); return; } else if (0 == rc) { continue; } - if (0 > (rc = tids_handle_request(&req, &resp))) { + /* Allocate a response structure and populate common fields */ + if ((NULL == (mresp = malloc(sizeof(TR_MSG)))) || + (NULL == (mresp->tid_resp = malloc(sizeof(TID_RESP))))) { + fprintf(stderr, "Error allocating response structure.\n"); + return; + } + + mresp->msg_type = TID_RESPONSE; + memset(mresp->tid_resp, 0, sizeof(TID_RESP)); + + /* TBD -- handle errors */ + mresp->tid_resp->result = TID_SUCCESS; /* presume success */ + mresp->tid_resp->rp_realm = tr_dup_name(mreq->tid_req->rp_realm); + mresp->tid_resp->realm = tr_dup_name(mreq->tid_req->realm); + mresp->tid_resp->comm = tr_dup_name(mreq->tid_req->comm); + if (mreq->tid_req->orig_coi) + mresp->tid_resp->orig_coi = tr_dup_name(mreq->tid_req->orig_coi); + + if (0 > (rc = tids_handle_request(tids, mreq, &mresp))) { fprintf(stderr, "Error from tids_handle_request(), rc = %d.\n", rc); return; } - if (0 > (rc = tids_send_response(conn, &gssctx, &resp))) { + if (0 > (rc = tids_send_response(tids, conn, &gssctx, mresp))) { fprintf(stderr, "Error from tids_send_response(), rc = %d.\n", rc); return; } @@ -218,10 +252,17 @@ int tids_start (TIDS_INSTANCE *tids, int listen = -1; int conn = -1; pid_t pid; + int optval = 1; - if (0 > (listen = tids_listen(TID_PORT))) + if (0 > (listen = tids_listen(tids, TID_PORT))) perror ("Error from tids_listen()"); + setsockopt(listen, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); + + /* store the caller's request handler & cookie */ + tids->req_handler = req_handler; + tids->cookie = cookie; + while(1) { /* accept incoming conns until we are stopped */ if (0 > (conn = accept(listen, NULL, NULL))) { @@ -236,7 +277,7 @@ int tids_start (TIDS_INSTANCE *tids, if (pid == 0) { close(listen); - tids_handle_connection(conn); + tids_handle_connection(tids, conn); close(conn); exit(0); } else { diff --git a/tr/tr_main.c b/tr/tr_main.c index 90bfd13..d413ef0 100644 --- a/tr/tr_main.c +++ b/tr/tr_main.c @@ -38,19 +38,13 @@ int static tids_req_handler (TIDS_INSTANCE * tids, TID_REQ *req, - TID_RESP *resp, + TID_RESP **resp, void *cookie) { printf("Request received! Realm = %s, Comm = %s\n", req->realm->buf, req->comm->buf); if (tids) tids->req_count++; - if ((NULL == (resp->realm = tr_dup_name(req->realm))) || - (NULL == (resp->comm = tr_dup_name(req->comm)))) { - printf ("Error in tid_dup_name, not responding.\n"); - return 1; - } - return 0; } @@ -73,7 +67,7 @@ int main (int argc, const char *argv[]) /* initialize the trust path query server instance */ if (0 == (tids = tids_create ())) { - printf ("Error initializing Trust Path Query Server instance.\n", err); + printf ("Error initializing Trust Path Query Server instance.\n"); return 1; } -- 2.1.4