mod_authn_file.c revision 75031befec2825183c13931fc3266b56ed575c3d
0ad489b182ebb3789322345e22cf750f88ae167and/* Licensed to the Apache Software Foundation (ASF) under one or more
0ad489b182ebb3789322345e22cf750f88ae167and * contributor license agreements. See the NOTICE file distributed with
0ad489b182ebb3789322345e22cf750f88ae167and * this work for additional information regarding copyright ownership.
17ade6df5ec233536985eb1c130a906c725dd614humbedooh * The ASF licenses this file to You under the Apache License, Version 2.0
0ad489b182ebb3789322345e22cf750f88ae167and * (the "License"); you may not use this file except in compliance with
0ad489b182ebb3789322345e22cf750f88ae167and * the License. You may obtain a copy of the License at
031b91a62d25106ae69d4693475c79618dd5e884fielding *
031b91a62d25106ae69d4693475c79618dd5e884fielding * http://www.apache.org/licenses/LICENSE-2.0
031b91a62d25106ae69d4693475c79618dd5e884fielding *
031b91a62d25106ae69d4693475c79618dd5e884fielding * Unless required by applicable law or agreed to in writing, software
031b91a62d25106ae69d4693475c79618dd5e884fielding * distributed under the License is distributed on an "AS IS" BASIS,
031b91a62d25106ae69d4693475c79618dd5e884fielding * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0ad489b182ebb3789322345e22cf750f88ae167and * See the License for the specific language governing permissions and
0ad489b182ebb3789322345e22cf750f88ae167and * limitations under the License.
0ad489b182ebb3789322345e22cf750f88ae167and */
0ad489b182ebb3789322345e22cf750f88ae167and
0ad489b182ebb3789322345e22cf750f88ae167and#include "apr_strings.h"
0ad489b182ebb3789322345e22cf750f88ae167and#include "apr_md5.h" /* for apr_password_validate */
0ad489b182ebb3789322345e22cf750f88ae167and
0ad489b182ebb3789322345e22cf750f88ae167and#include "ap_config.h"
0ad489b182ebb3789322345e22cf750f88ae167and#include "ap_provider.h"
0ad489b182ebb3789322345e22cf750f88ae167and#include "httpd.h"
0ad489b182ebb3789322345e22cf750f88ae167and#include "http_config.h"
0ad489b182ebb3789322345e22cf750f88ae167and#include "http_core.h"
0ad489b182ebb3789322345e22cf750f88ae167and#include "http_log.h"
0ad489b182ebb3789322345e22cf750f88ae167and#include "http_protocol.h"
0ad489b182ebb3789322345e22cf750f88ae167and#include "http_request.h"
0ad489b182ebb3789322345e22cf750f88ae167and
0ad489b182ebb3789322345e22cf750f88ae167and#include "mod_auth.h"
0ad489b182ebb3789322345e22cf750f88ae167and
0ad489b182ebb3789322345e22cf750f88ae167andtypedef struct {
0ad489b182ebb3789322345e22cf750f88ae167and char *pwfile;
0ad489b182ebb3789322345e22cf750f88ae167and} authn_file_config_rec;
0ad489b182ebb3789322345e22cf750f88ae167and
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniakstatic void *create_authn_file_dir_config(apr_pool_t *p, char *d)
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak{
0ad489b182ebb3789322345e22cf750f88ae167and authn_file_config_rec *conf = apr_palloc(p, sizeof(*conf));
0ad489b182ebb3789322345e22cf750f88ae167and
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak conf->pwfile = NULL; /* just to illustrate the default really */
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak return conf;
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak}
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniakstatic const char *set_authn_file_slot(cmd_parms *cmd, void *offset,
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak const char *f, const char *t)
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak{
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak if (t && strcmp(t, "standard")) {
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak return apr_pstrcat(cmd->pool, "Invalid auth file type: ", t, NULL);
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak }
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak return ap_set_file_slot(cmd, offset, f);
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak}
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniakstatic const command_rec authn_file_cmds[] =
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak{
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak AP_INIT_TAKE12("AuthUserFile", set_authn_file_slot,
0ad489b182ebb3789322345e22cf750f88ae167and (void *)APR_OFFSETOF(authn_file_config_rec, pwfile),
0ad489b182ebb3789322345e22cf750f88ae167and OR_AUTHCFG, "text file containing user IDs and passwords"),
0ad489b182ebb3789322345e22cf750f88ae167and {NULL}
0ad489b182ebb3789322345e22cf750f88ae167and};
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniakmodule AP_MODULE_DECLARE_DATA authn_file_module;
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniakstatic authn_status check_password(request_rec *r, const char *user,
0ad489b182ebb3789322345e22cf750f88ae167and const char *password)
0ad489b182ebb3789322345e22cf750f88ae167and{
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak authn_file_config_rec *conf = ap_get_module_config(r->per_dir_config,
0ad489b182ebb3789322345e22cf750f88ae167and &authn_file_module);
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak ap_configfile_t *f;
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak char l[MAX_STRING_LEN];
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak apr_status_t status;
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak char *file_password = NULL;
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak
0ad489b182ebb3789322345e22cf750f88ae167and status = ap_pcfg_openfile(&f, r->pool, conf->pwfile);
0ad489b182ebb3789322345e22cf750f88ae167and
0ad489b182ebb3789322345e22cf750f88ae167and if (status != APR_SUCCESS) {
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak "Could not open password file: %s", conf->pwfile);
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak return AUTH_GENERAL_ERROR;
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak }
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak const char *rpw, *w;
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak /* Skip # or blank lines. */
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak if ((l[0] == '#') || (!l[0])) {
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak continue;
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak }
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak rpw = l;
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak w = ap_getword(r->pool, &rpw, ':');
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak if (!strcmp(user, w)) {
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak file_password = ap_getword(r->pool, &rpw, ':');
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak break;
0ad489b182ebb3789322345e22cf750f88ae167and }
0ad489b182ebb3789322345e22cf750f88ae167and }
0ad489b182ebb3789322345e22cf750f88ae167and ap_cfg_closefile(f);
0ad489b182ebb3789322345e22cf750f88ae167and
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak if (!file_password) {
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak return AUTH_USER_NOT_FOUND;
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak }
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak status = apr_password_validate(password, file_password);
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak if (status != APR_SUCCESS) {
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak return AUTH_DENIED;
0ad489b182ebb3789322345e22cf750f88ae167and }
0ad489b182ebb3789322345e22cf750f88ae167and
0ad489b182ebb3789322345e22cf750f88ae167and return AUTH_GRANTED;
0ad489b182ebb3789322345e22cf750f88ae167and}
0ad489b182ebb3789322345e22cf750f88ae167and
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniakstatic authn_status get_realm_hash(request_rec *r, const char *user,
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak const char *realm, char **rethash)
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak{
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak authn_file_config_rec *conf = ap_get_module_config(r->per_dir_config,
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak &authn_file_module);
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak ap_configfile_t *f;
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak char l[MAX_STRING_LEN];
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak apr_status_t status;
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak char *file_hash = NULL;
0ad489b182ebb3789322345e22cf750f88ae167and
0ad489b182ebb3789322345e22cf750f88ae167and status = ap_pcfg_openfile(&f, r->pool, conf->pwfile);
0ad489b182ebb3789322345e22cf750f88ae167and
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak if (status != APR_SUCCESS) {
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak "Could not open password file: %s", conf->pwfile);
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak return AUTH_GENERAL_ERROR;
0ad489b182ebb3789322345e22cf750f88ae167and }
0ad489b182ebb3789322345e22cf750f88ae167and
0ad489b182ebb3789322345e22cf750f88ae167and while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
0ad489b182ebb3789322345e22cf750f88ae167and const char *rpw, *w, *x;
0ad489b182ebb3789322345e22cf750f88ae167and
0ad489b182ebb3789322345e22cf750f88ae167and /* Skip # or blank lines. */
0ad489b182ebb3789322345e22cf750f88ae167and if ((l[0] == '#') || (!l[0])) {
0ad489b182ebb3789322345e22cf750f88ae167and continue;
0ad489b182ebb3789322345e22cf750f88ae167and }
0ad489b182ebb3789322345e22cf750f88ae167and
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak rpw = l;
0ad489b182ebb3789322345e22cf750f88ae167and w = ap_getword(r->pool, &rpw, ':');
0ad489b182ebb3789322345e22cf750f88ae167and x = ap_getword(r->pool, &rpw, ':');
0ad489b182ebb3789322345e22cf750f88ae167and
0ad489b182ebb3789322345e22cf750f88ae167and if (x && w && !strcmp(user, w) && !strcmp(realm, x)) {
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak /* Remember that this is a md5 hash of user:realm:password. */
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak file_hash = ap_getword(r->pool, &rpw, ':');
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak break;
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak }
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak }
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak ap_cfg_closefile(f);
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak if (!file_hash) {
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak return AUTH_USER_NOT_FOUND;
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak }
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak *rethash = file_hash;
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak return AUTH_USER_FOUND;
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak}
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak
0ad489b182ebb3789322345e22cf750f88ae167andstatic const authn_provider authn_file_provider =
0ad489b182ebb3789322345e22cf750f88ae167and{
0ad489b182ebb3789322345e22cf750f88ae167and &check_password,
0ad489b182ebb3789322345e22cf750f88ae167and &get_realm_hash,
0ad489b182ebb3789322345e22cf750f88ae167and};
0ad489b182ebb3789322345e22cf750f88ae167and
0ad489b182ebb3789322345e22cf750f88ae167andstatic void register_hooks(apr_pool_t *p)
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak{
0ad489b182ebb3789322345e22cf750f88ae167and ap_register_auth_provider(p, AUTHN_PROVIDER_GROUP, "file",
0ad489b182ebb3789322345e22cf750f88ae167and AUTHN_PROVIDER_VERSION,
0ad489b182ebb3789322345e22cf750f88ae167and &authn_file_provider, AP_AUTH_INTERNAL_PER_CONF);
0ad489b182ebb3789322345e22cf750f88ae167and}
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniakmodule AP_MODULE_DECLARE_DATA authn_file_module =
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak{
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak STANDARD20_MODULE_STUFF,
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak create_authn_file_dir_config, /* dir config creater */
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak NULL, /* dir merger --- default is to override */
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak NULL, /* server config */
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak NULL, /* merge server config */
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak authn_file_cmds, /* command apr_table_t */
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak register_hooks /* register hooks */
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak};
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak