X-Git-Url: http://www.project-moonshot.org/gitweb/?p=trust_router.git;a=blobdiff_plain;f=common%2Ftr_gss.c;h=d5764497c2489d00e3fb3af91fb2beea92e453c9;hp=39a13a973d77a9812bfaf023ee18169cdd6069e4;hb=6454056a45ff204133fd53f7f147e46ffb397d4f;hpb=98be752015619fab5d29405bea10158a0e26d044 diff --git a/common/tr_gss.c b/common/tr_gss.c index 39a13a9..d576449 100644 --- a/common/tr_gss.c +++ b/common/tr_gss.c @@ -73,6 +73,7 @@ static int tr_gss_auth_cb(gss_name_t clientName, gss_buffer_t displayName, void TR_NAME name ={(char *) displayName->value, (int) displayName->length}; int result=0; + tr_debug("tr_gss_auth_cb: Calling auth handler for %.*s.", name.len, name.buf); if (cookie->auth_cb(clientName, &name, cookie->auth_cookie)) { tr_debug("tr_gss_auth_cb: client '%.*s' denied authorization.", name.len, name.buf); result=EACCES; /* denied */ @@ -86,16 +87,16 @@ static int tr_gss_auth_cb(gss_name_t clientName, gss_buffer_t displayName, void * Handle GSS authentication and authorization * * @param conn connection file descriptor - * @param acceptor_name name of acceptor to present to initiator - * @param acceptor_realm realm of acceptor to present to initiator + * @param acceptor_service name of acceptor to present to initiator + * @param acceptor_hostname hostname of acceptor to present to initiator * @param gssctx GSS context * @param auth_cb authorization callback * @param auth_cookie generic data to pass to the authorization callback * @return 0 on successful auth, 1 on disallowed auth, -1 on error */ static int tr_gss_auth_connection(int conn, - const char *acceptor_name, - const char *acceptor_realm, + const char *acceptor_service, + const char *acceptor_hostname, gss_ctx_id_t *gssctx, TR_GSS_AUTH_FN auth_cb, void *auth_cookie) @@ -105,7 +106,7 @@ static int tr_gss_auth_connection(int conn, gss_buffer_desc nameBuffer = {0, NULL}; TR_GSS_COOKIE *cookie = NULL; - nameBuffer.value = talloc_asprintf(NULL, "%s@%s", acceptor_name, acceptor_realm); + nameBuffer.value = talloc_asprintf(NULL, "%s@%s", acceptor_service, acceptor_hostname); if (nameBuffer.value == NULL) { tr_err("tr_gss_auth_connection: Error allocating acceptor name."); return -1; @@ -120,6 +121,8 @@ static int tr_gss_auth_connection(int conn, cookie->auth_cookie=auth_cookie; /* Now call gsscon with *our* auth callback and cookie */ + tr_debug("tr_gss_auth_connection: Beginning passive authentication as %.*s", + nameBuffer.length, nameBuffer.value); rc = gsscon_passive_authenticate(conn, nameBuffer, gssctx, tr_gss_auth_cb, cookie); talloc_free(cookie); talloc_free(nameBuffer.value); @@ -128,6 +131,7 @@ static int tr_gss_auth_connection(int conn, return -1; } + tr_debug("tr_gss_auth_connection: Authentication succeeded, now authorizing."); rc = gsscon_authorize(*gssctx, &auth, &autherr); if (rc) { tr_debug("tr_gss_auth_connection: Error from gsscon_authorize, rc = %d, autherr = %d.", @@ -203,29 +207,36 @@ static int tr_gss_write_resp(int conn, gss_ctx_id_t gssctx, const char *resp) * callback to get a response, sends that, then returns. * * @param conn connection file descriptor - * @param acceptor_name acceptor name to present - * @param acceptor_realm acceptor realm to present + * @param acceptor_service acceptor name to present + * @param acceptor_hostname acceptor hostname to present * @param auth_cb callback for authorization * @param auth_cookie cookie for the auth_cb * @param req_cb callback to handle the request and produce the response * @param req_cookie cookie for the req_cb */ -void tr_gss_handle_connection(int conn, - const char *acceptor_name, - const char *acceptor_realm, - TR_GSS_AUTH_FN auth_cb, - void *auth_cookie, - TR_GSS_HANDLE_REQ_FN req_cb, - void *req_cookie) +TR_GSS_RC tr_gss_handle_connection(int conn, + const char *acceptor_service, + const char *acceptor_hostname, + TR_GSS_AUTH_FN auth_cb, + void *auth_cookie, + TR_GSS_HANDLE_REQ_FN req_cb, + void *req_cookie) { TALLOC_CTX *tmp_ctx = talloc_new(NULL); gss_ctx_id_t gssctx = GSS_C_NO_CONTEXT; char *req_str = NULL; + size_t req_len = 0; + TR_MSG *req_msg = NULL; + TR_MSG *resp_msg = NULL; char *resp_str = NULL; + TR_GSS_RC rc = TR_GSS_ERROR; + + tr_debug("tr_gss_handle_connection: Attempting to accept %s connection on fd %d.", + acceptor_service, conn); if (tr_gss_auth_connection(conn, - acceptor_name, - acceptor_realm, + acceptor_service, + acceptor_hostname, &gssctx, auth_cb, auth_cookie)) { @@ -236,36 +247,58 @@ void tr_gss_handle_connection(int conn, tr_debug("tr_gss_handle_connection: Connection authorized"); // TODO: should there be a timeout on this? - while (1) { /* continue until an error breaks us out */ + do { + /* continue until an error breaks us out */ // try to read a request req_str = tr_gss_read_req(tmp_ctx, conn, gssctx); - if ( req_str == NULL) { + if (req_str == NULL) { // an error occurred, give up tr_notice("tr_gss_handle_connection: Error reading request"); goto cleanup; - } else if (strlen(req_str) > 0) { - // we got a request message, exit the loop and process it - break; } - // no error, but no message, keep waiting for one - talloc_free(req_str); // this would be cleaned up anyway, but may as well free it + req_len = strlen(req_str); + + /* If we got no characters, we will loop again. Free the empty response for the next loop. */ + if (req_len == 0) + talloc_free(req_str); + + } while (req_len == 0); + + /* Decode the request */ + req_msg = tr_msg_decode(tmp_ctx, req_str, req_len); + if (req_msg == NULL) { + tr_notice("tr_gss_handle_connection: Error decoding response"); + goto cleanup; } /* Hand off the request for processing and get the response */ - resp_str = req_cb(tmp_ctx, req_str, req_cookie); + resp_msg = req_cb(tmp_ctx, req_msg, req_cookie); - if (resp_str == NULL) { + if (resp_msg == NULL) { // no response, clean up goto cleanup; } + /* Encode the response */ + resp_str = tr_msg_encode(tmp_ctx, resp_msg); + if (resp_str == NULL) { + /* We apparently can't encode a response, so just return */ + tr_err("tr_gss_handle_connection: Error encoding response"); + goto cleanup; + } + // send the response if (tr_gss_write_resp(conn, gssctx, resp_str)) { - tr_notice("tr_gss_handle_connection: Error writing response"); + tr_err("tr_gss_handle_connection: Error writing response"); + goto cleanup; } + /* we successfully sent a response */ + rc = TR_GSS_SUCCESS; + cleanup: talloc_free(tmp_ctx); + return rc; }