#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include <tr_dh.h>
{
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 */
/* 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");
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;
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;
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 */
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;
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#include <string.h>
#include <openssl/dh.h>
#include <jansson.h>
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");
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;
}
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");
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;
}
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);
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;
}
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");
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));
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;
}
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;
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;
}
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;
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);
}
#include <openssl/dh.h>
#include <openssl/bn.h>
+#include <trust_router/tr_versioning.h>
-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
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;
/* 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);
}
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;
}
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;
*/
#include <stdio.h>
+#include <string.h>
#include <trust_router/tid.h>
+#include <tr_dh.h>
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[])
/* 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);
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)))) ||
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);
if (resp_buf)
free(resp_buf);
+ /* TBD -- free the decoded response */
+
return 0;
}
#include <jansson.h>
#include <gsscon.h>
+#include <tr_msg.h>
#include <trust_router/tid.h>
-
-static int tids_listen (int port)
+static int tids_listen (TIDS_INSTANCE *tids, int port)
{
int rc = 0;
int conn = -1;
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;
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)) {
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;
}
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))) {
if (pid == 0) {
close(listen);
- tids_handle_connection(conn);
+ tids_handle_connection(tids, conn);
close(conn);
exit(0);
} else {
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;
}
/* 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;
}