| /* 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. |
| */ |
| |
| /* |
| * Adapted to allow anonymous logins, just like with Anon-FTP, when |
| * one gives the magic user name 'anonymous' and ones email address |
| * as the password. |
| * |
| * Just add the following tokes to your <directory> setup: |
| * |
| * Anonymous magic-userid [magic-userid]... |
| * |
| * Anonymous_MustGiveEmail [ on | off ] default = on |
| * Anonymous_LogEmail [ on | off ] default = on |
| * Anonymous_VerifyEmail [ on | off ] default = off |
| * Anonymous_NoUserId [ on | off ] default = off |
| * |
| * The magic user id is something like 'anonymous', it is NOT case sensitive. |
| * |
| * The MustGiveEmail flag can be used to force users to enter something |
| * in the password field (like an email address). Default is on. |
| * |
| * Furthermore the 'NoUserID' flag can be set to allow completely empty |
| * usernames in as well; this can be is convenient as a single return |
| * in broken GUIs like W95 is often given by the user. The Default is off. |
| * |
| * Dirk.vanGulik@jrc.it; http://ewse.ceo.org; http://me-www.jrc.it/~dirkx |
| * |
| */ |
| |
| #include "apr_strings.h" |
| |
| #define APR_WANT_STRFUNC |
| #include "apr_want.h" |
| |
| #include "ap_provider.h" |
| #include "httpd.h" |
| #include "http_config.h" |
| #include "http_core.h" |
| #include "http_log.h" |
| #include "http_request.h" |
| #include "http_protocol.h" |
| |
| #include "mod_auth.h" |
| |
| typedef struct anon_auth_user { |
| const char *user; |
| struct anon_auth_user *next; |
| } anon_auth_user; |
| |
| typedef struct { |
| anon_auth_user *users; |
| int nouserid; |
| int logemail; |
| int verifyemail; |
| int mustemail; |
| int anyuserid; |
| } authn_anon_config_rec; |
| |
| static void *create_authn_anon_dir_config(apr_pool_t *p, char *d) |
| { |
| authn_anon_config_rec *conf = apr_palloc(p, sizeof(*conf)); |
| |
| /* just to illustrate the defaults really. */ |
| conf->users = NULL; |
| |
| conf->nouserid = 0; |
| conf->anyuserid = 0; |
| conf->logemail = 1; |
| conf->verifyemail = 0; |
| conf->mustemail = 1; |
| return conf; |
| } |
| |
| static const char *anon_set_string_slots(cmd_parms *cmd, |
| void *my_config, const char *arg) |
| { |
| authn_anon_config_rec *conf = my_config; |
| anon_auth_user *first; |
| |
| if (!*arg) { |
| return "Anonymous string cannot be empty, use Anonymous_NoUserId"; |
| } |
| |
| /* squeeze in a record */ |
| if (!conf->anyuserid) { |
| if (!strcmp(arg, "*")) { |
| conf->anyuserid = 1; |
| } |
| else { |
| first = conf->users; |
| conf->users = apr_palloc(cmd->pool, sizeof(*conf->users)); |
| conf->users->user = arg; |
| conf->users->next = first; |
| } |
| } |
| |
| return NULL; |
| } |
| |
| static const command_rec authn_anon_cmds[] = |
| { |
| AP_INIT_ITERATE("Anonymous", anon_set_string_slots, NULL, OR_AUTHCFG, |
| "a space-separated list of user IDs"), |
| AP_INIT_FLAG("Anonymous_MustGiveEmail", ap_set_flag_slot, |
| (void *)APR_OFFSETOF(authn_anon_config_rec, mustemail), |
| OR_AUTHCFG, "Limited to 'on' or 'off'"), |
| AP_INIT_FLAG("Anonymous_NoUserId", ap_set_flag_slot, |
| (void *)APR_OFFSETOF(authn_anon_config_rec, nouserid), |
| OR_AUTHCFG, "Limited to 'on' or 'off'"), |
| AP_INIT_FLAG("Anonymous_VerifyEmail", ap_set_flag_slot, |
| (void *)APR_OFFSETOF(authn_anon_config_rec, verifyemail), |
| OR_AUTHCFG, "Limited to 'on' or 'off'"), |
| AP_INIT_FLAG("Anonymous_LogEmail", ap_set_flag_slot, |
| (void *)APR_OFFSETOF(authn_anon_config_rec, logemail), |
| OR_AUTHCFG, "Limited to 'on' or 'off'"), |
| {NULL} |
| }; |
| |
| module AP_MODULE_DECLARE_DATA authn_anon_module; |
| |
| static authn_status check_anonymous(request_rec *r, const char *user, |
| const char *sent_pw) |
| { |
| authn_anon_config_rec *conf = ap_get_module_config(r->per_dir_config, |
| &authn_anon_module); |
| authn_status res = AUTH_USER_NOT_FOUND; |
| |
| /* Ignore if we are not configured */ |
| if (!conf->users && !conf->anyuserid) { |
| return AUTH_USER_NOT_FOUND; |
| } |
| |
| /* Do we allow an empty userID and/or is it the magic one |
| */ |
| if (!*user) { |
| if (conf->nouserid) { |
| res = AUTH_USER_FOUND; |
| } |
| } |
| else if (conf->anyuserid) { |
| res = AUTH_USER_FOUND; |
| } |
| else { |
| anon_auth_user *p = conf->users; |
| |
| while (p) { |
| if (!strcasecmp(user, p->user)) { |
| res = AUTH_USER_FOUND; |
| break; |
| } |
| p = p->next; |
| } |
| } |
| |
| /* Now if the supplied user-ID was ok, grant access if: |
| * (a) no passwd was sent and no password and no verification |
| * were configured. |
| * (b) password was sent and no verification was configured |
| * (c) verification was configured and the password (sent or not) |
| * looks like an email address |
| */ |
| if ( (res == AUTH_USER_FOUND) |
| && (!conf->mustemail || *sent_pw) |
| && ( !conf->verifyemail |
| || (ap_strchr_c(sent_pw, '@') && ap_strchr_c(sent_pw, '.')))) |
| { |
| if (conf->logemail && ap_is_initial_req(r)) { |
| ap_log_rerror(APLOG_MARK, APLOG_INFO, APR_SUCCESS, r, APLOGNO(01672) |
| "Anonymous: Passwd <%s> Accepted", |
| sent_pw ? sent_pw : "\'none\'"); |
| } |
| |
| return AUTH_GRANTED; |
| } |
| |
| return (res == AUTH_USER_NOT_FOUND ? res : AUTH_DENIED); |
| } |
| |
| static const authn_provider authn_anon_provider = |
| { |
| &check_anonymous, |
| NULL |
| }; |
| |
| static void register_hooks(apr_pool_t *p) |
| { |
| ap_register_auth_provider(p, AUTHN_PROVIDER_GROUP, "anon", |
| AUTHN_PROVIDER_VERSION, |
| &authn_anon_provider, AP_AUTH_INTERNAL_PER_CONF); |
| } |
| |
| AP_DECLARE_MODULE(authn_anon) = |
| { |
| STANDARD20_MODULE_STUFF, |
| create_authn_anon_dir_config, /* dir config creater */ |
| NULL, /* dir merger ensure strictness */ |
| NULL, /* server config */ |
| NULL, /* merge server config */ |
| authn_anon_cmds, /* command apr_table_t */ |
| register_hooks /* register hooks */ |
| }; |