X-Git-Url: http://www.project-moonshot.org/gitweb/?p=mod_auth_gssapi.git;a=blobdiff_plain;f=src%2Fmod_auth_gssapi.c;h=4f21123a4caa56d748307055be73099cc9a63dc0;hp=4ba543e585a830d67489540f168809fea006b444;hb=e9c92795d87a316ea47f6bf37c9636e86eec57e7;hpb=7407b64481bc49ad552f9ba0ff2efe1f6fb0982e diff --git a/src/mod_auth_gssapi.c b/src/mod_auth_gssapi.c index 4ba543e..4f21123 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; + const char *orig_ccache = NULL; +#endif type = ap_auth_type(req); if ((type == NULL) || (strcasecmp(type, "GSSAPI") != 0)) { @@ -255,26 +259,14 @@ static int mag_auth(request_rec *req) input.value = apr_pcalloc(req->pool, input.length); if (!input.value) goto done; input.length = apr_base64_decode(input.value, auth_header_value); - } else if (strcasecmp(auth_header_type, "Basic") == 0) { + } else if ((strcasecmp(auth_header_type, "Basic") == 0) && + (cfg->use_basic_auth == true)) { auth_type = "Basic"; is_basic = true; gss_buffer_desc ba_user; gss_buffer_desc ba_pwd; - switch (cfg->basic_auth) { - case BA_ON: - /* handle directly */ - break; - case BA_FORWARD: - /* decline to handle ourselves, let other modules do it */ - ret = DECLINED; - goto done; - case BA_OFF: - goto done; - default: - goto done; - } ba_pwd.value = ap_pbase64decode(req->pool, auth_header); if (!ba_pwd.value) goto done; ba_user.value = ap_getword_nulls_nc(req->pool, @@ -296,6 +288,28 @@ 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, &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, @@ -483,7 +497,7 @@ done: } else { apr_table_add(req->err_headers_out, "WWW-Authenticate", "Negotiate"); - if (cfg->basic_auth != BA_OFF) { + if (cfg->use_basic_auth) { apr_table_add(req->err_headers_out, "WWW-Authenticate", apr_psprintf(req->pool, "Basic realm=\"%s\"", @@ -491,6 +505,17 @@ 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)); + } + } +#endif gss_delete_sec_context(&min, &user_ctx, &output); gss_release_cred(&min, &user_cred); gss_release_cred(&min, &acquired_cred); @@ -561,7 +586,7 @@ static const char *mag_use_s4u2p(cmd_parms *parms, void *mconfig, int on) static const char *mag_sess_key(cmd_parms *parms, void *mconfig, const char *w) { struct mag_config *cfg = (struct mag_config *)mconfig; - struct databuf keys; + struct databuf key; unsigned char *val; apr_status_t rc; const char *k; @@ -582,16 +607,16 @@ static const char *mag_sess_key(cmd_parms *parms, void *mconfig, const char *w) return NULL; } - keys.length = (int)apr_base64_decode_binary(val, k); - keys.value = (unsigned char *)val; + key.length = (int)apr_base64_decode_binary(val, k); + key.value = (unsigned char *)val; - if (keys.length != 32) { + if (key.length < 32) { ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, parms->server, - "Invalid key lenght, expected 32 got %d", keys.length); + "Invalid key length, expected >=32 got %d", key.length); return NULL; } - rc = SEAL_KEY_CREATE(cfg->pool, &cfg->mag_skey, &keys); + rc = SEAL_KEY_CREATE(cfg->pool, &cfg->mag_skey, &key); if (rc != OK) { ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, parms->server, "Failed to import sealing key!"); @@ -674,19 +699,11 @@ static const char *mag_deleg_ccache_dir(cmd_parms *parms, void *mconfig, return NULL; } -static const char *mag_use_basic_auth(cmd_parms *parms, void *mconfig, - const char *value) +static const char *mag_use_basic_auth(cmd_parms *parms, void *mconfig, int on) { struct mag_config *cfg = (struct mag_config *)mconfig; - if (strcasecmp(value, "on") == 0) { - cfg->basic_auth = BA_ON; - } else if (strcasecmp(value, "forward") == 0) { - cfg->basic_auth = BA_FORWARD; - } else { - cfg->basic_auth = BA_OFF; - } - + cfg->use_basic_auth = on ? true : false; return NULL; } @@ -712,7 +729,7 @@ static const command_rec mag_commands[] = { OR_AUTHCFG, "Directory to store delegated credentials"), #endif #ifdef HAVE_GSS_ACQUIRE_CRED_WITH_PASSWORD - AP_INIT_TAKE1("GssapiBasicAuth", mag_use_basic_auth, NULL, OR_AUTHCFG, + AP_INIT_FLAG("GssapiBasicAuth", mag_use_basic_auth, NULL, OR_AUTHCFG, "Allows use of Basic Auth for authentication"), #endif { NULL }