]> granicus.if.org Git - apache/blob - modules/aaa/mod_authz_host.c
Remove the call to ap_note_auth_failure() from the providers. mod_authz_core will...
[apache] / modules / aaa / mod_authz_host.c
1 /* Copyright 2002-2005 The Apache Software Foundation or its licensors, as
2  * applicable.
3  *
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 /*
18  * Security options etc.
19  *
20  * Module derived from code originally written by Rob McCool
21  *
22  */
23
24 #include "apr_strings.h"
25 #include "apr_network_io.h"
26 #include "apr_md5.h"
27
28 #define APR_WANT_STRFUNC
29 #define APR_WANT_BYTEFUNC
30 #include "apr_want.h"
31
32 #include "ap_config.h"
33 #include "ap_provider.h"
34 #include "httpd.h"
35 #include "http_core.h"
36 #include "http_config.h"
37 #include "http_log.h"
38 #include "http_protocol.h"
39 #include "http_request.h"
40
41 #include "mod_auth.h"
42
43 #if APR_HAVE_NETINET_IN_H
44 #include <netinet/in.h>
45 #endif
46
47 typedef struct {
48         int dummy;  /* just here to stop compiler warnings for now. */
49 } authz_host_dir_conf;
50
51 module AP_MODULE_DECLARE_DATA authz_host_module;
52
53 static void *create_authz_host_dir_config(apr_pool_t *p, char *dummy)
54 {
55     authz_host_dir_conf *conf =
56         (authz_host_dir_conf *)apr_pcalloc(p, sizeof(authz_host_dir_conf));
57
58     return (void *)conf;
59 }
60
61 static const command_rec authz_host_cmds[] =
62 {
63     {NULL}
64 };
65
66 static int in_domain(const char *domain, const char *what)
67 {
68     int dl = strlen(domain);
69     int wl = strlen(what);
70
71     if ((wl - dl) >= 0) {
72         if (strcasecmp(domain, &what[wl - dl]) != 0) {
73             return 0;
74         }
75
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.
79          */
80
81         if (wl == dl) {
82             return 1;                /* matched whole thing */
83         }
84         else {
85             return (domain[0] == '.' || what[wl - dl - 1] == '.');
86         }
87     }
88     else {
89         return 0;
90     }
91 }
92
93 static authz_status env_check_authorization(request_rec *r, const char *require_line)
94 {
95     const char *t, *w;
96
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. */
100     t = require_line;
101     while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
102         if (apr_table_get(r->subprocess_env, w)) {
103             return AUTHZ_GRANTED;
104         }
105     }
106
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",
110                   r->uri, r->user);
111
112     return AUTHZ_DENIED;
113 }
114
115 static authz_status ip_check_authorization(request_rec *r, const char *require_line)
116 {
117     const char *t, *w;
118
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. */
122     t = require_line;
123     while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
124         char *where = apr_pstrdup(r->pool, w);
125         char *s;
126         char msgbuf[120];
127         apr_ipsubnet_t *ip;
128         apr_status_t rv;
129         int got_ip = 0;
130
131         if ((s = ap_strchr(where, '/'))) {
132             *s++ = '\0';
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 ");
138             }
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 ",
143                               msgbuf);
144             }
145             else
146                 got_ip = 1;
147         }
148         else if (!APR_STATUS_IS_EINVAL(rv = apr_ipsubnet_create(&ip, where,
149                                                                 NULL, r->pool))) {
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 ",
154                               msgbuf);
155             }
156             else 
157                 got_ip = 1;
158         }
159
160         if (got_ip && apr_ipsubnet_test(ip, r->connection->remote_addr)) {
161             return AUTHZ_GRANTED;
162         }
163     }
164
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",
168                   r->uri, r->user);
169
170     return AUTHZ_DENIED;
171 }
172
173 static authz_status host_check_authorization(request_rec *r, const char *require_line)
174 {
175     const char *t, *w;
176     const char *remotehost = NULL;
177     int remotehost_is_ip;
178
179     remotehost = ap_get_remote_host(r->connection,
180                                     r->per_dir_config,
181                                     REMOTE_DOUBLE_REV,
182                                     &remotehost_is_ip);
183
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);
188     }
189     else {
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. */
193         t = require_line;
194         while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
195             if (in_domain(w, remotehost)) {
196                 return AUTHZ_GRANTED;
197             }
198         }
199
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",
203                       r->uri, r->user);
204     }
205
206     return AUTHZ_DENIED;
207 }
208
209 static authz_status all_check_authorization(request_rec *r, const char *require_line)
210 {
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;
218     }
219     return AUTHZ_DENIED;
220 }
221
222 static const authz_provider authz_env_provider =
223 {
224     &env_check_authorization,
225 };
226
227 static const authz_provider authz_ip_provider =
228 {
229     &ip_check_authorization,
230 };
231
232 static const authz_provider authz_host_provider =
233 {
234     &host_check_authorization,
235 };
236
237 static const authz_provider authz_all_provider =
238 {
239     &all_check_authorization,
240 };
241
242 static void register_hooks(apr_pool_t *p)
243 {
244     ap_register_provider(p, AUTHZ_PROVIDER_GROUP, "env", "0",
245                          &authz_env_provider);
246     ap_register_provider(p, AUTHZ_PROVIDER_GROUP, "ip", "0",
247                          &authz_ip_provider);
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);
252 }
253
254 module AP_MODULE_DECLARE_DATA authz_host_module =
255 {
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 */
261     authz_host_cmds,
262     register_hooks                  /* register hooks */
263 };