Someone asked on IRC today about seemlessly mixing SSL Client
authentication (FakeBasicAuth) with normal basic authn.
As I understood it, users without a client cert should authenticate, 
but those with one would be spared the authn dialogue.

A quick look at mod_ssl reveals that FakeBasicAuth sets r->user
in an Access hook, so it's set before authn.  So what the user
asks is trivial: all it needs is an authn provider that accepts
any request in which r->user is set.  I've just hacked up the
smallest-ever(?) module (attached) to do that.

This could also give users flexibility to mix-and-match basic
auth with other schemes in mod_rewrite style.  Or no doubt
shoot themselves in the foot.

Thoughts?

-- 
Nick Kew
/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "httpd.h"
#include "http_request.h"
#include "http_config.h"
#include "ap_provider.h"
#include "mod_auth.h"

module AP_MODULE_DECLARE_DATA authn_fake_module;

static authn_status check_fake(request_rec *r, const char *u, const char *p)
{
    return (r->user == NULL) ? AUTH_USER_NOT_FOUND : AUTH_GRANTED;
}

static void register_hooks(apr_pool_t *p)
{
    static const authn_provider authn_fake_provider = {
        &check_fake,
        NULL,
    };
#if AP_MODULE_MAGIC_AT_LEAST(20100000,0)
    ap_register_auth_provider(p, AUTHN_PROVIDER_GROUP, "fake",
                              AUTHN_PROVIDER_VERSION,
                              &authn_fake_provider, AP_AUTH_INTERNAL_PER_CONF);
#else
    ap_register_provider(p, AUTHN_PROVIDER_GROUP, "fake", "0",
                         &authn_fake_provider);
#endif
}

#if AP_MODULE_MAGIC_AT_LEAST(20100000,0)
AP_DECLARE_MODULE(authn_fake) =
#else
module AP_MODULE_DECLARE_DATA authn_fake_module =
#endif
{
    STANDARD20_MODULE_STUFF,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    register_hooks
};

Reply via email to