Improve Basic Auth based logins
authorSimo Sorce <simo@redhat.com>
Tue, 10 Mar 2015 16:23:12 +0000 (12:23 -0400)
committerSimo Sorce <simo@redhat.com>
Tue, 10 Mar 2015 19:27:12 +0000 (15:27 -0400)
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

configure.ac
src/mod_auth_gssapi.c
src/mod_auth_gssapi.h

index 78f31a2..7be2b7e 100644 (file)
@@ -53,7 +53,8 @@ PKG_CHECK_MODULES([OPENSSL], [openssl])
 AC_SUBST([OPENSSL_CFLAGS])
 AC_SUBST([OPENSSL_LIBS])
 
-AC_CHECK_HEADERS([gssapi/gssapi.h],,[AC_MSG_ERROR([Could not find GSSAPI headers])])
+AC_CHECK_HEADERS([gssapi/gssapi.h gssapi/gssapi_ext.h gssapi/gssapi_krb5.h],
+                 ,[AC_MSG_ERROR([Could not find GSSAPI headers])])
 AC_PATH_PROG(KRB5_CONFIG, krb5-config, failed)
 if test x$KRB5_CONFIG = xfailed; then
     AC_MSG_ERROR([Could not find GSSAPI development libraries])
@@ -66,6 +67,7 @@ AC_CHECK_LIB([gssapi_krb5], [gss_accept_sec_context], [],
 AC_CHECK_FUNCS(gss_acquire_cred_from)
 AC_CHECK_FUNCS(gss_store_cred_into)
 AC_CHECK_FUNCS(gss_acquire_cred_with_password)
+AC_CHECK_FUNCS(gss_krb5_ccache_name)
 
 AC_SUBST([GSSAPI_CFLAGS])
 AC_SUBST([GSSAPI_LIBS])
index aed0c3b..db87c10 100644 (file)
@@ -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);
index efe230d..4cf7d39 100644 (file)
@@ -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"