summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2015-03-10 12:23:12 -0400
committerSimo Sorce <simo@redhat.com>2015-03-10 15:27:12 -0400
commit3effbe272147674cf92c13b387373a60f2cbbacf (patch)
tree9a933e4ab27b17e5759f52737d3432c555ad4aaf /src
parent2b95bf742f097b419b4e63ef74f33fc121c91bf0 (diff)
downloadmod_auth_gssapi-3effbe272147674cf92c13b387373a60f2cbbacf.tar.gz
mod_auth_gssapi-3effbe272147674cf92c13b387373a60f2cbbacf.tar.xz
mod_auth_gssapi-3effbe272147674cf92c13b387373a60f2cbbacf.zip
Improve Basic Auth based logins
Set a per-thread Credentials Cache Name that will be thrown away once authentication is done. This handles both an issue with stomping on ccaches if two authentications happen in concurrent threads, as well as issues with gss_acquire_cred_with_password() reusing the ccache without actually performing an AS request. Fixes #11
Diffstat (limited to 'src')
-rw-r--r--src/mod_auth_gssapi.c40
-rw-r--r--src/mod_auth_gssapi.h1
2 files changed, 41 insertions, 0 deletions
diff --git a/src/mod_auth_gssapi.c b/src/mod_auth_gssapi.c
index aed0c3b..db87c10 100644
--- a/src/mod_auth_gssapi.c
+++ b/src/mod_auth_gssapi.c
@@ -183,6 +183,10 @@ static int mag_auth(request_rec *req)
bool is_basic = false;
gss_ctx_id_t user_ctx = GSS_C_NO_CONTEXT;
gss_name_t server = GSS_C_NO_NAME;
+#ifdef HAVE_GSS_KRB5_CCACHE_NAME
+ const char *user_ccache = NULL;
+ char *orig_ccache = NULL;
+#endif
type = ap_auth_type(req);
if ((type == NULL) || (strcasecmp(type, "GSSAPI") != 0)) {
@@ -284,6 +288,29 @@ static int mag_auth(request_rec *req)
maj, min));
goto done;
}
+#ifdef HAVE_GSS_KRB5_CCACHE_NAME
+ /* Set a per-thread ccache in case we are using kerberos,
+ * it is not elegant but avoids interference between threads */
+ long long unsigned int rndname;
+ apr_status_t rs;
+ rs = apr_generate_random_bytes((unsigned char *)(&rndname),
+ sizeof(long long unsigned int));
+ if (rs != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, req,
+ "Failed to generate random ccache name");
+ goto done;
+ }
+ user_ccache = apr_psprintf(req->pool, "MEMORY:user_%qu", rndname);
+ maj = gss_krb5_ccache_name(&min, user_ccache,
+ (const char **)&orig_ccache);
+ if (GSS_ERROR(maj)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, req,
+ "In Basic Auth, %s",
+ mag_error(req, "gss_krb5_ccache_name() "
+ "failed", maj, min));
+ goto done;
+ }
+#endif
maj = gss_acquire_cred_with_password(&min, client, &ba_pwd,
GSS_C_INDEFINITE,
GSS_C_NO_OID_SET,
@@ -479,6 +506,19 @@ done:
}
}
}
+#ifdef HAVE_GSS_KRB5_CCACHE_NAME
+ if (user_ccache != NULL) {
+ maj = gss_krb5_ccache_name(&min, orig_ccache, NULL);
+ if (maj != GSS_S_COMPLETE) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, req,
+ "Failed to restore per-thread ccache, %s",
+ mag_error(req, "gss_krb5_ccache_name() "
+ "failed", maj, min));
+ }
+ }
+ free(orig_ccache);
+ orig_ccache = NULL;
+#endif
gss_delete_sec_context(&min, &user_ctx, &output);
gss_release_cred(&min, &user_cred);
gss_release_cred(&min, &acquired_cred);
diff --git a/src/mod_auth_gssapi.h b/src/mod_auth_gssapi.h
index efe230d..4cf7d39 100644
--- a/src/mod_auth_gssapi.h
+++ b/src/mod_auth_gssapi.h
@@ -5,6 +5,7 @@
#include <time.h>
#include <gssapi/gssapi.h>
#include <gssapi/gssapi_ext.h>
+#include <gssapi/gssapi_krb5.h>
#define APR_WANT_STRFUNC
#include "apr_want.h"