1 /* Copyright 2002-2005 The Apache Software Foundation or its licensors, as
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * Security options etc.
20 * Module derived from code originally written by Rob McCool
24 #include "apr_strings.h"
25 #include "apr_network_io.h"
28 #define APR_WANT_STRFUNC
29 #define APR_WANT_BYTEFUNC
32 #include "ap_config.h"
33 #include "ap_provider.h"
35 #include "http_core.h"
36 #include "http_config.h"
38 #include "http_protocol.h"
39 #include "http_request.h"
43 #if APR_HAVE_NETINET_IN_H
44 #include <netinet/in.h>
48 int dummy; /* just here to stop compiler warnings for now. */
49 } authz_host_dir_conf;
51 module AP_MODULE_DECLARE_DATA authz_host_module;
53 static void *create_authz_host_dir_config(apr_pool_t *p, char *dummy)
55 authz_host_dir_conf *conf =
56 (authz_host_dir_conf *)apr_pcalloc(p, sizeof(authz_host_dir_conf));
61 static const command_rec authz_host_cmds[] =
66 static int in_domain(const char *domain, const char *what)
68 int dl = strlen(domain);
69 int wl = strlen(what);
72 if (strcasecmp(domain, &what[wl - dl]) != 0) {
76 /* Make sure we matched an *entire* subdomain --- if the user
77 * said 'allow from good.com', we don't want people from nogood.com
78 * to be able to get in.
82 return 1; /* matched whole thing */
85 return (domain[0] == '.' || what[wl - dl - 1] == '.');
93 static authz_status env_check_authorization(request_rec *r, const char *require_line)
97 /* The 'env' provider will allow the configuration to specify a list of
98 env variables to check rather than a single variable. This is different
99 from the previous host based syntax. */
101 while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
102 if (apr_table_get(r->subprocess_env, w)) {
103 return AUTHZ_GRANTED;
107 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
108 "access to %s failed, reason: env variable list does not meet "
109 "'require'ments for user '%s' to be allowed access",
115 static authz_status ip_check_authorization(request_rec *r, const char *require_line)
119 /* The 'ip' provider will allow the configuration to specify a list of
120 ip addresses to check rather than a single address. This is different
121 from the previous host based syntax. */
123 while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
124 char *where = apr_pstrdup(r->pool, w);
131 if ((s = ap_strchr(where, '/'))) {
133 rv = apr_ipsubnet_create(&ip, where, s, r->pool);
134 if(APR_STATUS_IS_EINVAL(rv)) {
135 /* looked nothing like an IP address */
136 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
137 "an ip address 'require' list appears to be invalid ");
139 else if (rv != APR_SUCCESS) {
140 apr_strerror(rv, msgbuf, sizeof msgbuf);
141 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
142 "an ip address 'require' list appears to be invalid; %s ",
148 else if (!APR_STATUS_IS_EINVAL(rv = apr_ipsubnet_create(&ip, where,
150 if (rv != APR_SUCCESS) {
151 apr_strerror(rv, msgbuf, sizeof msgbuf);
152 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
153 "an ip address 'require' list appears to be invalid; %s ",
160 if (got_ip && apr_ipsubnet_test(ip, r->connection->remote_addr)) {
161 return AUTHZ_GRANTED;
165 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
166 "access to %s failed, reason: ip address list does not meet "
167 "'require'ments for user '%s' to be allowed access",
173 static authz_status host_check_authorization(request_rec *r, const char *require_line)
176 const char *remotehost = NULL;
177 int remotehost_is_ip;
179 remotehost = ap_get_remote_host(r->connection,
184 if ((remotehost == NULL) || remotehost_is_ip) {
185 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
186 "access to %s failed, reason: unable to get the "
187 "remote host name", r->uri);
190 /* The 'host' provider will allow the configuration to specify a list of
191 host names to check rather than a single name. This is different
192 from the previous host based syntax. */
194 while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
195 if (in_domain(w, remotehost)) {
196 return AUTHZ_GRANTED;
200 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
201 "access to %s failed, reason: host name list does not meet "
202 "'require'ments for user '%s' to be allowed access",
209 static authz_status all_check_authorization(request_rec *r, const char *require_line)
211 /* If the argument to the 'all' provider is 'granted' then just let
212 everybody in. This would be equivalent to the previous syntax of
213 'allow from all'. If the argument is anything else, this would
214 be equivalent to 'deny from all' Of course the opposite would be
215 true if the 'all' provider is invoked by the 'reject' directive */
216 if (strcasecmp(require_line, "granted") == 0) {
217 return AUTHZ_GRANTED;
222 static const authz_provider authz_env_provider =
224 &env_check_authorization,
227 static const authz_provider authz_ip_provider =
229 &ip_check_authorization,
232 static const authz_provider authz_host_provider =
234 &host_check_authorization,
237 static const authz_provider authz_all_provider =
239 &all_check_authorization,
242 static void register_hooks(apr_pool_t *p)
244 ap_register_provider(p, AUTHZ_PROVIDER_GROUP, "env", "0",
245 &authz_env_provider);
246 ap_register_provider(p, AUTHZ_PROVIDER_GROUP, "ip", "0",
248 ap_register_provider(p, AUTHZ_PROVIDER_GROUP, "host", "0",
249 &authz_host_provider);
250 ap_register_provider(p, AUTHZ_PROVIDER_GROUP, "all", "0",
251 &authz_all_provider);
254 module AP_MODULE_DECLARE_DATA authz_host_module =
256 STANDARD20_MODULE_STUFF,
257 create_authz_host_dir_config, /* dir config creater */
258 NULL, /* dir merger --- default is to override */
259 NULL, /* server config */
260 NULL, /* merge server config */
262 register_hooks /* register hooks */