X-Git-Url: http://www.project-moonshot.org/gitweb/?p=trust_router.git;a=blobdiff_plain;f=tr%2Ftr_tid.c;h=6cd0eb5d4d2a18a8d9bfdfaeccd056f44eec1643;hp=6bc002aca55300a29f3f157f37d9e3a0e73ac5b8;hb=605ee6f071ad51755ba07b4e1a712814bbf4f780;hpb=e71ac4f7f1666dff5b21c9e6a57bf2a01f9ab469 diff --git a/tr/tr_tid.c b/tr/tr_tid.c index 6bc002a..6cd0eb5 100644 --- a/tr/tr_tid.c +++ b/tr/tr_tid.c @@ -243,6 +243,8 @@ static int tr_tids_req_handler(TIDS_INSTANCE *tids, pthread_t aaa_thread[TR_TID_MAX_AAA_SERVERS]; struct tr_tids_fwd_cookie *aaa_cookie[TR_TID_MAX_AAA_SERVERS]={NULL}; TID_RESP *aaa_resp[TR_TID_MAX_AAA_SERVERS]={NULL}; + TR_RP_CLIENT *rp_client=NULL; + TR_RP_CLIENT_ITER *rpc_iter=NULL; TR_NAME *apc = NULL; TID_REQ *fwd_req = NULL; TR_COMM *cfg_comm = NULL; @@ -290,13 +292,13 @@ static int tr_tids_req_handler(TIDS_INSTANCE *tids, goto cleanup; } - /* Check that the rp_realm matches the filter for the GSS name that - * was received. N.B. that tids->rp_gss was pointed at the correct - * rp_client when we received its GSS name. It is only set within - * the TIDS handler subprocess. */ + /* We now need to apply the filters associated with the RP client handing us the request. + * It is possible (or even likely) that more than one client is associated with the GSS + * name we got from the authentication. We will apply all of them in an arbitrary order. + * For this to result in well-defined behavior, either only accept or only reject filter + * lines should be used, or a unique GSS name must be given for each RP realm. */ - if ((!tids->rp_gss) || - (!tids->rp_gss->filters)) { + if (!tids->gss_name) { tr_notice("tr_tids_req_handler: No GSS name for incoming request."); tids_send_err_response(tids, orig_req, "No GSS name for request"); retval=-1; @@ -309,21 +311,42 @@ static int tr_tids_req_handler(TIDS_INSTANCE *tids, target=tr_filter_target_tid_req(tmp_ctx, orig_req); if (target==NULL) { - /* TODO: signal that filtering failed. Until then, just filter everything and give an error message. */ tr_crit("tid_req_handler: Unable to allocate filter target, cannot apply filter!"); + tids_send_err_response(tids, orig_req, "Incoming TID request filter error"); + retval=-1; + goto cleanup; } - if ((target==NULL) - || (TR_FILTER_NO_MATCH == tr_filter_apply(target, - tr_filter_set_get(tids->rp_gss->filters, - TR_FILTER_TYPE_TID_INBOUND), - &(fwd_req->cons), - &oaction)) - || (TR_FILTER_ACTION_ACCEPT != oaction)) { - tr_notice("tr_tids_req_handler: RP realm (%s) does not match RP Realm filter for GSS name", orig_req->rp_realm->buf); - tids_send_err_response(tids, orig_req, "RP Realm filter error"); + + rpc_iter=tr_rp_client_iter_new(tmp_ctx); + if (rpc_iter==NULL) { + tr_err("tid_req_handler: Unable to allocate RP client iterator."); retval=-1; goto cleanup; } + for (rp_client=tr_rp_client_iter_first(rpc_iter, cfg_mgr->active->rp_clients); + rp_client != NULL; + rp_client=tr_rp_client_iter_next(rpc_iter)) { + + if (!tr_gss_names_matches(rp_client->gss_names, tids->gss_name)) + continue; /* skip any that don't match the GSS name */ + + if (TR_FILTER_MATCH == tr_filter_apply(target, + tr_filter_set_get(rp_client->filters, + TR_FILTER_TYPE_TID_INBOUND), + &(fwd_req->cons), + &oaction)) + break; /* Stop looking, oaction is set */ + } + + /* We get here whether or not a filter matched. If tr_filter_apply() doesn't match, it returns + * a default action of reject, so we don't have to check why we exited the loop. */ + if (oaction != TR_FILTER_ACTION_ACCEPT) { + tr_notice("tr_tids_req_handler: Incoming TID request rejected by filter for GSS name", orig_req->rp_realm->buf); + tids_send_err_response(tids, orig_req, "Incoming TID request filter error"); + retval = -1; + goto cleanup; + } + /* Check that the rp_realm is a member of the community in the request */ if (NULL == tr_comm_find_rp(cfg_mgr->active->ctable, cfg_comm, orig_req->rp_realm)) { tr_notice("tr_tids_req_handler: RP Realm (%s) not member of community (%s).", orig_req->rp_realm->buf, orig_req->comm->buf); @@ -376,38 +399,32 @@ static int tr_tids_req_handler(TIDS_INSTANCE *tids, tr_debug("tr_tids_req_handler: looking up route."); route=trps_get_selected_route(trps, orig_req->comm, orig_req->realm); if (route==NULL) { - tr_notice("tr_tids_req_handler: no route table entry found for realm (%s) in community (%s).", - orig_req->realm->buf, orig_req->comm->buf); - tids_send_err_response(tids, orig_req, "Missing trust route error"); - retval=-1; - goto cleanup; - } - tr_debug("tr_tids_req_handler: found route."); - if (trp_route_is_local(route)) { - tr_debug("tr_tids_req_handler: route is local."); - aaa_servers = tr_idp_aaa_server_lookup(cfg_mgr->active->ctable->idp_realms, - orig_req->realm, - orig_req->comm, - &idp_shared); - } else { - tr_debug("tr_tids_req_handler: route not local."); - aaa_servers = tr_aaa_server_new(tmp_ctx, trp_route_get_next_hop(route)); - idp_shared=0; - } - - /* Find the AAA server(s) for this request */ - if (NULL == aaa_servers) { - tr_debug("tr_tids_req_handler: No AAA Servers for realm %s, defaulting.", orig_req->realm->buf); - if (NULL == (aaa_servers = tr_default_server_lookup (cfg_mgr->active->default_servers, - orig_req->comm))) { + /* No route. Use default AAA servers if we have them. */ + tr_debug("tr_tids_req_handler: No route for realm %s, defaulting.", orig_req->realm->buf); + if (NULL == (aaa_servers = tr_default_server_lookup(cfg_mgr->active->default_servers, + orig_req->comm))) { tr_notice("tr_tids_req_handler: No default AAA servers, discarded."); tids_send_err_response(tids, orig_req, "No path to AAA Server(s) for realm"); - retval=-1; + retval = -1; goto cleanup; } - idp_shared=0; + idp_shared = 0; } else { - /* if we aren't defaulting, check idp coi and apc membership */ + /* Found a route. Determine the AAA servers or next hop address. */ + tr_debug("tr_tids_req_handler: found route."); + if (trp_route_is_local(route)) { + tr_debug("tr_tids_req_handler: route is local."); + aaa_servers = tr_idp_aaa_server_lookup(cfg_mgr->active->ctable->idp_realms, + orig_req->realm, + orig_req->comm, + &idp_shared); + } else { + tr_debug("tr_tids_req_handler: route not local."); + aaa_servers = tr_aaa_server_new(tmp_ctx, trp_route_get_next_hop(route)); + idp_shared = 0; + } + + /* Since we aren't defaulting, check idp coi and apc membership */ if (NULL == (tr_comm_find_idp(cfg_mgr->active->ctable, cfg_comm, fwd_req->realm))) { tr_notice("tr_tids_req_handler: IDP Realm (%s) not member of community (%s).", orig_req->realm->buf, orig_req->comm->buf); tids_send_err_response(tids, orig_req, "IDP community membership error"); @@ -422,6 +439,15 @@ static int tr_tids_req_handler(TIDS_INSTANCE *tids, } } + /* Make sure we came through with a AAA server. If not, we can't handle the request. */ + if (NULL == aaa_servers) { + tr_notice("tr_tids_req_handler: no route or AAA server for realm (%s) in community (%s).", + orig_req->realm->buf, orig_req->comm->buf); + tids_send_err_response(tids, orig_req, "Missing trust route error"); + retval = -1; + goto cleanup; + } + /* send a TID request to the AAA server(s), and get the answer(s) */ tr_debug("tr_tids_req_handler: sending TID request(s)."); if (cfg_apc) @@ -602,7 +628,6 @@ cleanup: static int tr_tids_gss_handler(gss_name_t client_name, TR_NAME *gss_name, void *data) { - TR_RP_CLIENT *rp; struct tr_tids_event_cookie *cookie=talloc_get_type_abort(data, struct tr_tids_event_cookie); TIDS_INSTANCE *tids = cookie->tids; TR_CFG_MGR *cfg_mgr = cookie->cfg_mgr; @@ -612,15 +637,15 @@ static int tr_tids_gss_handler(gss_name_t client_name, TR_NAME *gss_name, return -1; } - /* look up the RP client matching the GSS name */ - if ((NULL == (rp = tr_rp_client_lookup(cfg_mgr->active->rp_clients, gss_name)))) { - tr_debug("tr_tids_gss_handler: Unknown GSS name %s", gss_name->buf); + /* Ensure at least one client exists using this GSS name */ + if (NULL == tr_rp_client_lookup(cfg_mgr->active->rp_clients, gss_name)) { + tr_debug("tr_tids_gss_handler: Unknown GSS name %.*s", gss_name->len, gss_name->buf); return -1; } - /* Store the rp client */ - tids->rp_gss = rp; - tr_debug("Client's GSS Name: %s", gss_name->buf); + /* Store the GSS name */ + tids->gss_name = tr_dup_name(gss_name); + tr_debug("Client's GSS Name: %.*s", gss_name->len, gss_name->buf); return 0; } @@ -651,7 +676,7 @@ int tr_tids_event_init(struct event_base *base, TALLOC_CTX *tmp_ctx=talloc_new(NULL); struct tr_tids_event_cookie *cookie=NULL; int retval=0; - size_t ii=0; + int ii=0; if (tids_ev == NULL) { tr_debug("tr_tids_event_init: Null tids_ev."); @@ -673,14 +698,14 @@ int tr_tids_event_init(struct event_base *base, talloc_steal(tids, cookie); /* get a tids listener */ - tids_ev->n_sock_fd=tids_get_listener(tids, - tr_tids_req_handler, - tr_tids_gss_handler, - cfg_mgr->active->internal->hostname, - cfg_mgr->active->internal->tids_port, - (void *)cookie, - tids_ev->sock_fd, - TR_MAX_SOCKETS); + tids_ev->n_sock_fd = (int)tids_get_listener(tids, + tr_tids_req_handler, + tr_tids_gss_handler, + cfg_mgr->active->internal->hostname, + cfg_mgr->active->internal->tids_port, + (void *)cookie, + tids_ev->sock_fd, + TR_MAX_SOCKETS); if (tids_ev->n_sock_fd==0) { tr_crit("Error opening TID server socket."); retval=1;