summaryrefslogtreecommitdiff
path: root/modules/aaa/mod_auth_basic.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/aaa/mod_auth_basic.c')
-rw-r--r--modules/aaa/mod_auth_basic.c155
1 files changed, 148 insertions, 7 deletions
diff --git a/modules/aaa/mod_auth_basic.c b/modules/aaa/mod_auth_basic.c
index cadeb5bd..8c1367b3 100644
--- a/modules/aaa/mod_auth_basic.c
+++ b/modules/aaa/mod_auth_basic.c
@@ -15,7 +15,6 @@
*/
#include "apr_strings.h"
-#include "apr_md5.h" /* for apr_password_validate */
#include "apr_lib.h" /* for apr_isspace */
#include "apr_base64.h" /* for apr_base64_decode et al */
#define APR_WANT_STRFUNC /* for strcasecmp */
@@ -29,26 +28,53 @@
#include "http_protocol.h"
#include "http_request.h"
#include "ap_provider.h"
+#include "ap_expr.h"
#include "mod_auth.h"
typedef struct {
authn_provider_list *providers;
- char *dir;
+ char *dir; /* unused variable */
int authoritative;
+ ap_expr_info_t *fakeuser;
+ ap_expr_info_t *fakepass;
+ int fake_set:1;
+ int authoritative_set:1;
} auth_basic_config_rec;
static void *create_auth_basic_dir_config(apr_pool_t *p, char *d)
{
auth_basic_config_rec *conf = apr_pcalloc(p, sizeof(*conf));
- conf->dir = d;
/* Any failures are fatal. */
conf->authoritative = 1;
return conf;
}
+static void *merge_auth_basic_dir_config(apr_pool_t *p, void *basev, void *overridesv)
+{
+ auth_basic_config_rec *newconf = apr_pcalloc(p, sizeof(*newconf));
+ auth_basic_config_rec *base = basev;
+ auth_basic_config_rec *overrides = overridesv;
+
+ newconf->authoritative =
+ overrides->authoritative_set ? overrides->authoritative :
+ base->authoritative;
+ newconf->authoritative_set = overrides->authoritative_set
+ || base->authoritative_set;
+
+ newconf->fakeuser =
+ overrides->fake_set ? overrides->fakeuser : base->fakeuser;
+ newconf->fakepass =
+ overrides->fake_set ? overrides->fakepass : base->fakepass;
+ newconf->fake_set = overrides->fake_set || base->fake_set;
+
+ newconf->providers = overrides->providers ? overrides->providers : base->providers;
+
+ return newconf;
+}
+
static const char *add_authn_provider(cmd_parms *cmd, void *config,
const char *arg)
{
@@ -94,15 +120,72 @@ static const char *add_authn_provider(cmd_parms *cmd, void *config,
return NULL;
}
+static const char *set_authoritative(cmd_parms * cmd, void *config, int flag)
+{
+ auth_basic_config_rec *conf = (auth_basic_config_rec *) config;
+
+ conf->authoritative = flag;
+ conf->authoritative_set = 1;
+
+ return NULL;
+}
+
+static const char *add_basic_fake(cmd_parms * cmd, void *config,
+ const char *user, const char *pass)
+{
+ auth_basic_config_rec *conf = (auth_basic_config_rec *) config;
+ const char *err;
+
+ if (!strcasecmp(user, "off")) {
+
+ conf->fakeuser = NULL;
+ conf->fakepass = NULL;
+ conf->fake_set = 1;
+
+ }
+ else {
+
+ /* if password is unspecified, set it to the fixed string "password" to
+ * be compatible with the behaviour of mod_ssl.
+ */
+ if (!pass) {
+ pass = "password";
+ }
+
+ conf->fakeuser =
+ ap_expr_parse_cmd(cmd, user, AP_EXPR_FLAG_STRING_RESULT,
+ &err, NULL);
+ if (err) {
+ return apr_psprintf(cmd->pool,
+ "Could not parse fake username expression '%s': %s", user,
+ err);
+ }
+ conf->fakepass =
+ ap_expr_parse_cmd(cmd, pass, AP_EXPR_FLAG_STRING_RESULT,
+ &err, NULL);
+ if (err) {
+ return apr_psprintf(cmd->pool,
+ "Could not parse fake password expression '%s': %s", user,
+ err);
+ }
+ conf->fake_set = 1;
+
+ }
+
+ return NULL;
+}
+
static const command_rec auth_basic_cmds[] =
{
AP_INIT_ITERATE("AuthBasicProvider", add_authn_provider, NULL, OR_AUTHCFG,
"specify the auth providers for a directory or location"),
- AP_INIT_FLAG("AuthBasicAuthoritative", ap_set_flag_slot,
- (void *)APR_OFFSETOF(auth_basic_config_rec, authoritative),
- OR_AUTHCFG,
+ AP_INIT_FLAG("AuthBasicAuthoritative", set_authoritative, NULL, OR_AUTHCFG,
"Set to 'Off' to allow access control to be passed along to "
"lower modules if the UserID is not known to this module"),
+ AP_INIT_TAKE12("AuthBasicFake", add_basic_fake, NULL, OR_AUTHCFG,
+ "Fake basic authentication using the given expressions for "
+ "username and password, 'off' to disable. Password defaults "
+ "to 'password' if missing."),
{NULL}
};
@@ -295,10 +378,68 @@ static int authenticate_basic_user(request_rec *r)
return OK;
}
+/* If requested, create a fake basic authentication header for the benefit
+ * of a proxy or application running behind this server.
+ */
+static int authenticate_basic_fake(request_rec *r)
+{
+ const char *auth_line, *user, *pass, *err;
+ auth_basic_config_rec *conf = ap_get_module_config(r->per_dir_config,
+ &auth_basic_module);
+
+ if (!conf->fakeuser) {
+ return DECLINED;
+ }
+
+ user = ap_expr_str_exec(r, conf->fakeuser, &err);
+ if (err) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02455)
+ "AuthBasicFake: could not evaluate user expression for URI '%s': %s", r->uri, err);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ if (!user || !*user) {
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02458)
+ "AuthBasicFake: empty username expression for URI '%s', ignoring", r->uri);
+
+ apr_table_unset(r->headers_in, "Authorization");
+
+ return DECLINED;
+ }
+
+ pass = ap_expr_str_exec(r, conf->fakepass, &err);
+ if (err) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02456)
+ "AuthBasicFake: could not evaluate password expression for URI '%s': %s", r->uri, err);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ if (!pass || !*pass) {
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02459)
+ "AuthBasicFake: empty password expression for URI '%s', ignoring", r->uri);
+
+ apr_table_unset(r->headers_in, "Authorization");
+
+ return DECLINED;
+ }
+
+ auth_line = apr_pstrcat(r->pool, "Basic ",
+ ap_pbase64encode(r->pool,
+ apr_pstrcat(r->pool, user,
+ ":", pass, NULL)),
+ NULL);
+ apr_table_setn(r->headers_in, "Authorization", auth_line);
+
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02457)
+ "AuthBasicFake: \"Authorization: %s\"",
+ auth_line);
+
+ return OK;
+}
+
static void register_hooks(apr_pool_t *p)
{
ap_hook_check_authn(authenticate_basic_user, NULL, NULL, APR_HOOK_MIDDLE,
AP_AUTH_INTERNAL_PER_CONF);
+ ap_hook_fixups(authenticate_basic_fake, NULL, NULL, APR_HOOK_LAST);
ap_hook_note_auth_failure(hook_note_basic_auth_failure, NULL, NULL,
APR_HOOK_MIDDLE);
}
@@ -307,7 +448,7 @@ AP_DECLARE_MODULE(auth_basic) =
{
STANDARD20_MODULE_STUFF,
create_auth_basic_dir_config, /* dir config creater */
- NULL, /* dir merger --- default is to override */
+ merge_auth_basic_dir_config, /* dir merger --- default is to override */
NULL, /* server config */
NULL, /* merge server config */
auth_basic_cmds, /* command apr_table_t */