X-Git-Url: http://www.project-moonshot.org/gitweb/?p=mod_auth_gssapi.git;a=blobdiff_plain;f=src%2Fmod_auth_gssapi.c;h=24cee3dac3ea5eb2b87fdccf35cb809984d13276;hp=8687568e5734258b7bcae74b6ef7c72a48d0ba5f;hb=10d352bac12353efb5fe6e6efd2655e0562a1f8e;hpb=c4aa3d46e334461988acf17596fd34a6baa82aa3 diff --git a/src/mod_auth_gssapi.c b/src/mod_auth_gssapi.c index 8687568..24cee3d 100644 --- a/src/mod_auth_gssapi.c +++ b/src/mod_auth_gssapi.c @@ -96,9 +96,7 @@ static int mag_pre_connection(conn_rec *c, void *csd) { struct mag_conn *mc; - mc = apr_pcalloc(c->pool, sizeof(struct mag_conn)); - - mc->parent = c->pool; + mc = mag_new_conn_ctx(c->pool); ap_set_module_config(c->conn_config, &auth_gssapi_module, (void*)mc); return OK; } @@ -110,11 +108,35 @@ static apr_status_t mag_conn_destroy(void *ptr) if (mc->ctx) { (void)gss_delete_sec_context(&min, &mc->ctx, GSS_C_NO_BUFFER); - mc->established = false; } return APR_SUCCESS; } +struct mag_conn *mag_new_conn_ctx(apr_pool_t *pool) +{ + struct mag_conn *mc; + + mc = apr_pcalloc(pool, sizeof(struct mag_conn)); + apr_pool_create(&mc->pool, pool); + /* register the context in the memory pool, so it can be freed + * when the connection/request is terminated */ + apr_pool_cleanup_register(mc->pool, (void *)mc, + mag_conn_destroy, apr_pool_cleanup_null); + + return mc; +} + +static void mag_conn_clear(struct mag_conn *mc) +{ + (void)mag_conn_destroy(mc); + apr_pool_t *temp; + + apr_pool_clear(mc->pool); + temp = mc->pool; + memset(mc, 0, sizeof(struct mag_conn)); + mc->pool = temp; +} + static bool mag_conn_is_https(conn_rec *c) { if (mag_is_https) { @@ -288,6 +310,28 @@ const char *auth_types[] = { NULL }; +static void mag_set_req_data(request_rec *req, + struct mag_config *cfg, + struct mag_conn *mc) +{ + apr_table_set(req->subprocess_env, "GSS_NAME", mc->gss_name); + apr_table_set(req->subprocess_env, "GSS_SESSION_EXPIRATION", + apr_psprintf(req->pool, + "%ld", (long)mc->expiration)); + req->ap_auth_type = apr_pstrdup(req->pool, + auth_types[mc->auth_type]); + req->user = apr_pstrdup(req->pool, mc->user_name); + if (cfg->deleg_ccache_dir && mc->delegated) { + char *ccname; + ccname = mag_gss_name_to_ccache_name(req, + cfg->deleg_ccache_dir, + mc->gss_name); + if (ccname) { + mag_set_KRB5CCANME(req, ccname); + } + } +} + static int mag_auth(request_rec *req) { const char *type; @@ -397,44 +441,22 @@ static int mag_auth(request_rec *req) mag_check_session(req, cfg, &mc); } - if (mc) { - /* register the context in the memory pool, so it can be freed - * when the connection/request is terminated */ - apr_pool_userdata_set(mc, "mag_conn_ptr", - mag_conn_destroy, mc->parent); + auth_header = apr_table_get(req->headers_in, "Authorization"); - if (mc->established) { + if (mc) { + if (mc->established && !auth_header) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, req, "Already established context found!"); - apr_table_set(req->subprocess_env, "GSS_NAME", mc->gss_name); - apr_table_set(req->subprocess_env, "GSS_SESSION_EXPIRATION", - apr_psprintf(req->pool, - "%ld", (long)mc->expiration)); - req->ap_auth_type = apr_pstrdup(req->pool, - auth_types[mc->auth_type]); - req->user = apr_pstrdup(req->pool, mc->user_name); - if (cfg->deleg_ccache_dir && mc->delegated) { - char *ccname; - ccname = mag_gss_name_to_ccache_name(req, - cfg->deleg_ccache_dir, - mc->gss_name); - if (ccname) { - mag_set_KRB5CCANME(req, ccname); - } - } - if (mc->auth_type != AUTH_TYPE_BASIC) { - /* In case we have basic auth, we need to check if the session - * matches the credentials that have been sent */ - ret = OK; - goto done; - } + mag_set_req_data(req, cfg, mc); + ret = OK; + goto done; } pctx = &mc->ctx; } else { pctx = &ctx; } - auth_header = apr_table_get(req->headers_in, "Authorization"); + /* We can proceed only if we do have an auth header */ if (!auth_header) goto done; auth_header_type = ap_getword_white(req->pool, &auth_header); @@ -447,6 +469,13 @@ static int mag_auth(request_rec *req) } } + if (mc && mc->established && auth_type != AUTH_TYPE_BASIC) { + /* if we are re-authenticating make sure the conn context + * is cleaned up so we do not accidentally reuse an existing + * established context */ + mag_conn_clear(mc); + } + switch (auth_type) { case AUTH_TYPE_NEGOTIATE: if (!parse_auth_header(req->pool, &auth_header, &input)) { @@ -472,9 +501,16 @@ static int mag_auth(request_rec *req) ba_user.length = strlen(ba_user.value); ba_pwd.length = strlen(ba_pwd.value); - if (mc && mag_basic_check(cfg, mc, ba_user, ba_pwd)) { - ret = OK; - goto done; + if (mc && mc->established) { + if (mag_basic_check(cfg, mc, ba_user, ba_pwd)) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, req, + "Already established BASIC AUTH context found!"); + mag_set_req_data(req, cfg, mc); + ret = OK; + goto done; + } else { + mag_conn_clear(mc); + } } maj = gss_import_name(&min, &ba_user, GSS_C_NT_USER_NAME, &client); @@ -650,7 +686,6 @@ static int mag_auth(request_rec *req) "Mechanism needs continuation but neither " "GssapiConnectionBound nor " "GssapiUseSessions are available"); - gss_delete_sec_context(&min, pctx, GSS_C_NO_BUFFER); gss_release_buffer(&min, &output); output.length = 0; } @@ -702,20 +737,20 @@ static int mag_auth(request_rec *req) } if (mc) { - mc->user_name = apr_pstrdup(mc->parent, req->user); - mc->gss_name = apr_pstrdup(mc->parent, clientname); + mc->user_name = apr_pstrdup(mc->pool, req->user); + mc->gss_name = apr_pstrdup(mc->pool, clientname); mc->established = true; if (vtime == GSS_C_INDEFINITE || vtime < MIN_SESS_EXP_TIME) { vtime = MIN_SESS_EXP_TIME; } mc->expiration = expiration; - if (cfg->use_sessions) { - mag_attempt_session(req, cfg, mc); - } mc->auth_type = auth_type; if (auth_type == AUTH_TYPE_BASIC) { mag_basic_cache(cfg, mc, ba_user, ba_pwd); } + if (cfg->use_sessions) { + mag_attempt_session(req, cfg, mc); + } } if (cfg->send_persist) @@ -759,7 +794,9 @@ done: } } #endif - gss_delete_sec_context(&min, &user_ctx, &output); + if (ctx != GSS_C_NO_CONTEXT) + gss_delete_sec_context(&min, &ctx, GSS_C_NO_BUFFER); + gss_delete_sec_context(&min, &user_ctx, GSS_C_NO_BUFFER); gss_release_cred(&min, &user_cred); gss_release_cred(&min, &acquired_cred); gss_release_cred(&min, &delegated_cred);