authn_status checkAuthnz()

in modules/server/mod-eval.hpp [1269:1330]


authn_status checkAuthnz(request_rec* r, const char* u, const char* p) {
    const gc_scoped_pool sp(r->pool);

    // Prevent FakeBasicAuth spoofing
    const string user = u;
    debug(user, "modeval::checkAuthnz::user");
    const bool extauth = find(user, "/") != length(user);
    if (extauth && substr(user, 0, 1) != "/") {
        mkfailure<int>(string("Encountered FakeBasicAuth spoof: ") + user, HTTP_UNAUTHORIZED);
        return AUTH_DENIED;
    }

    // Get the server configuration
    const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_eval);
    if (isNull(sc.vhostc.authenticator)) {
        mkfailure<int>("SCA authenticator not configured");
        return AUTH_GENERAL_ERROR;
    }

    // Retrieve the user's password hash
    const list<value> uid = extauth? cdr(pathValues(user)) : pathValues(user);
    const failable<value> val = failableResult(((value)sc.vhostc.authenticator)(cons<value>("get", mklist<value>(uid))));
    if (!hasContent(val) || isNull(content(val))) {
        mkfailure<int>(string("SCA authentication check user failed, user not found: ") + user, rcode(val), user != "admin");
        return AUTH_USER_NOT_FOUND;
    }
    debug(content(val), "modeval::checkAuthnz::val");

    const value authn = cdr<value>(car<value>(content(val)));
    const list<value> acontent = assoc<value>(value("content"), authn);
    const list<value> aauthn = isNull(acontent)? nilListValue : assoc<value>(value("authn"), cdr<value>(acontent));
    const list<value> ahash = isNull(aauthn)? nilListValue : assoc<value>(value("hash"), cdr<value>(aauthn));
    if (isNull(ahash)) {
        mkfailure<int>(string("SCA authentication check user failed, hash not found: ") + user, -1, user != "admin");
        return AUTH_USER_NOT_FOUND;
    }
    const string uhash = cadr<value>(ahash);
    if (length(uhash) == 0) {
        mkfailure<int>(string("SCA authentication check user failed: ") + user);
        return AUTH_USER_NOT_FOUND;
    }

    // Use a fixed hash of the string 'password' for externally authenticated users as they
    // don't present an actual password
    const string hash = extauth? "$apr1$OPUrN0Kr$/tc96p1r6LdmvB0mly6gg0" : uhash;

    // Validate the password against the hash
    const apr_status_t rv = apr_password_validate(p, c_str(hash));
    if (rv != APR_SUCCESS) {
        mkfailure<int>(string("SCA authentication user password check failed: ") + user);
        return AUTH_DENIED;
    }

    // Update the user field of the request with the authenticated user
    const list<value> auser = assoc<value>(value("user"), cdr<value>(aauthn));
    if (!isNull(auser)) {
        debug(c_str(cadr(auser)), "modeval::checkAuthnz::auth_user");
        apr_table_set(r->subprocess_env, "AUTHZ_USER", apr_pstrdup(r->pool, c_str(cadr(auser))));
    }

    return AUTH_GRANTED;
}