Skip to content

Commit 3effbe2

Browse files
committed
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
1 parent 2b95bf7 commit 3effbe2

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

configure.ac

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ PKG_CHECK_MODULES([OPENSSL], [openssl])
5353
AC_SUBST([OPENSSL_CFLAGS])
5454
AC_SUBST([OPENSSL_LIBS])
5555

56-
AC_CHECK_HEADERS([gssapi/gssapi.h],,[AC_MSG_ERROR([Could not find GSSAPI headers])])
56+
AC_CHECK_HEADERS([gssapi/gssapi.h gssapi/gssapi_ext.h gssapi/gssapi_krb5.h],
57+
,[AC_MSG_ERROR([Could not find GSSAPI headers])])
5758
AC_PATH_PROG(KRB5_CONFIG, krb5-config, failed)
5859
if test x$KRB5_CONFIG = xfailed; then
5960
AC_MSG_ERROR([Could not find GSSAPI development libraries])
@@ -66,6 +67,7 @@ AC_CHECK_LIB([gssapi_krb5], [gss_accept_sec_context], [],
6667
AC_CHECK_FUNCS(gss_acquire_cred_from)
6768
AC_CHECK_FUNCS(gss_store_cred_into)
6869
AC_CHECK_FUNCS(gss_acquire_cred_with_password)
70+
AC_CHECK_FUNCS(gss_krb5_ccache_name)
6971

7072
AC_SUBST([GSSAPI_CFLAGS])
7173
AC_SUBST([GSSAPI_LIBS])

src/mod_auth_gssapi.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,10 @@ static int mag_auth(request_rec *req)
183183
bool is_basic = false;
184184
gss_ctx_id_t user_ctx = GSS_C_NO_CONTEXT;
185185
gss_name_t server = GSS_C_NO_NAME;
186+
#ifdef HAVE_GSS_KRB5_CCACHE_NAME
187+
const char *user_ccache = NULL;
188+
char *orig_ccache = NULL;
189+
#endif
186190

187191
type = ap_auth_type(req);
188192
if ((type == NULL) || (strcasecmp(type, "GSSAPI") != 0)) {
@@ -284,6 +288,29 @@ static int mag_auth(request_rec *req)
284288
maj, min));
285289
goto done;
286290
}
291+
#ifdef HAVE_GSS_KRB5_CCACHE_NAME
292+
/* Set a per-thread ccache in case we are using kerberos,
293+
* it is not elegant but avoids interference between threads */
294+
long long unsigned int rndname;
295+
apr_status_t rs;
296+
rs = apr_generate_random_bytes((unsigned char *)(&rndname),
297+
sizeof(long long unsigned int));
298+
if (rs != APR_SUCCESS) {
299+
ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, req,
300+
"Failed to generate random ccache name");
301+
goto done;
302+
}
303+
user_ccache = apr_psprintf(req->pool, "MEMORY:user_%qu", rndname);
304+
maj = gss_krb5_ccache_name(&min, user_ccache,
305+
(const char **)&orig_ccache);
306+
if (GSS_ERROR(maj)) {
307+
ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, req,
308+
"In Basic Auth, %s",
309+
mag_error(req, "gss_krb5_ccache_name() "
310+
"failed", maj, min));
311+
goto done;
312+
}
313+
#endif
287314
maj = gss_acquire_cred_with_password(&min, client, &ba_pwd,
288315
GSS_C_INDEFINITE,
289316
GSS_C_NO_OID_SET,
@@ -479,6 +506,19 @@ static int mag_auth(request_rec *req)
479506
}
480507
}
481508
}
509+
#ifdef HAVE_GSS_KRB5_CCACHE_NAME
510+
if (user_ccache != NULL) {
511+
maj = gss_krb5_ccache_name(&min, orig_ccache, NULL);
512+
if (maj != GSS_S_COMPLETE) {
513+
ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, req,
514+
"Failed to restore per-thread ccache, %s",
515+
mag_error(req, "gss_krb5_ccache_name() "
516+
"failed", maj, min));
517+
}
518+
}
519+
free(orig_ccache);
520+
orig_ccache = NULL;
521+
#endif
482522
gss_delete_sec_context(&min, &user_ctx, &output);
483523
gss_release_cred(&min, &user_cred);
484524
gss_release_cred(&min, &acquired_cred);

src/mod_auth_gssapi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <time.h>
66
#include <gssapi/gssapi.h>
77
#include <gssapi/gssapi_ext.h>
8+
#include <gssapi/gssapi_krb5.h>
89

910
#define APR_WANT_STRFUNC
1011
#include "apr_want.h"

0 commit comments

Comments
 (0)