Apache HTTPD
mod_authz_host.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. 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#include "apr_hash.h"
28
29#define APR_WANT_STRFUNC
30#define APR_WANT_BYTEFUNC
31#include "apr_want.h"
32
33#include "ap_config.h"
34#include "ap_provider.h"
35#include "httpd.h"
36#include "http_core.h"
37#include "http_config.h"
38#include "http_log.h"
39#include "http_protocol.h"
40#include "http_request.h"
41
42#include "mod_auth.h"
43
44#if APR_HAVE_NETINET_IN_H
45#include <netinet/in.h>
46#endif
47
48/*
49 * To save memory if the same subnets are used in hundres of vhosts, we store
50 * each subnet only once and use this temporary hash to find it again.
51 */
53
55#if APR_HAVE_IPV6
57#endif
58
59static int in_domain(const char *domain, const char *what)
60{
61 int dl = strlen(domain);
62 int wl = strlen(what);
63
64 if ((wl - dl) >= 0) {
65 if (strcasecmp(domain, &what[wl - dl]) != 0) {
66 return 0;
67 }
68
69 /* Make sure we matched an *entire* subdomain --- if the user
70 * said 'allow from good.com', we don't want people from nogood.com
71 * to be able to get in.
72 */
73
74 if (wl == dl) {
75 return 1; /* matched whole thing */
76 }
77 else {
78 return (domain[0] == '.' || what[wl - dl - 1] == '.');
79 }
80 }
81 else {
82 return 0;
83 }
84}
85
86static const char *ip_parse_config(cmd_parms *cmd,
87 const char *require_line,
88 const void **parsed_require_line)
89{
90 const char *t, *w;
91 int count = 0;
92 apr_ipsubnet_t **ip;
93 apr_pool_t *ptemp = cmd->temp_pool;
94 apr_pool_t *p = cmd->pool;
95
96 /* The 'ip' provider will allow the configuration to specify a list of
97 ip addresses to check rather than a single address. This is different
98 from the previous host based syntax. */
99
100 t = require_line;
101 while ((w = ap_getword_conf(ptemp, &t)) && w[0])
102 count++;
103
104 if (count == 0)
105 return "'require ip' requires an argument";
106
107 ip = apr_pcalloc(p, sizeof(apr_ipsubnet_t *) * (count + 1));
109
110 t = require_line;
111 while ((w = ap_getword_conf(ptemp, &t)) && w[0]) {
112 char *addr = apr_pstrdup(ptemp, w);
113 char *mask;
114 apr_status_t rv;
115
116 if (parsed_subnets &&
118 {
119 /* we already have parsed this subnet */
120 ip++;
121 continue;
122 }
123
124 if ((mask = ap_strchr(addr, '/')))
125 *mask++ = '\0';
126
127 rv = apr_ipsubnet_create(ip, addr, mask, p);
128
129 if(APR_STATUS_IS_EINVAL(rv)) {
130 /* looked nothing like an IP address */
131 return apr_psprintf(p, "ip address '%s' appears to be invalid", w);
132 }
133 else if (rv != APR_SUCCESS) {
134 return apr_psprintf(p, "ip address '%s' appears to be invalid: %pm",
135 w, &rv);
136 }
137
138 if (parsed_subnets)
140 ip++;
141 }
142
143 return NULL;
144}
145
147 const char *require_line,
148 const void *parsed_require_line)
149{
150 /* apr_ipsubnet_test should accept const but doesn't */
152
153 while (*ip) {
155 return AUTHZ_GRANTED;
156 ip++;
157 }
158
159 /* authz_core will log the require line and the result at DEBUG */
160 return AUTHZ_DENIED;
161}
162
164 const char *require_line,
165 const void *parsed_require_line)
166{
167 const char *t, *w;
168 const char *remotehost = NULL;
170
172
173 if ((remotehost == NULL) || remotehost_is_ip) {
175 "access check of '%s' to %s failed, reason: unable to get the "
176 "remote host name", require_line, r->uri);
177 }
178 else {
179 const char *err = NULL;
181 const char *require;
182
183 require = ap_expr_str_exec(r, expr, &err);
184 if (err) {
186 "authz_host authorize: require host: Can't "
187 "evaluate require expression: %s", err);
188 return AUTHZ_DENIED;
189 }
190
191 /* The 'host' provider will allow the configuration to specify a list of
192 host names to check rather than a single name. This is different
193 from the previous host based syntax. */
194 t = require;
195
196 /* '#' is not a valid hostname character and admin could
197 * specify 'Require host localhost# Add example.com later'. We
198 * should not grant access to 'example.com' in that case. */
199 w = ap_strchr_c(t, '#');
200 if (w) {
201 if (w == t) {
203 "authz_host authorize: dubious empty "
204 "'Require host %s' with only comment", t);
205 return AUTHZ_DENIED;
206 }
207
209 "authz_host authorize: ignoring comment in "
210 "'Require host %s'", t);
211
212 /* Truncate the string at the #. */
213 t = apr_pstrmemdup(r->pool, t, w - t);
214 }
215
216 while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
217 if (in_domain(w, remotehost)) {
218 return AUTHZ_GRANTED;
219 }
220 }
221 }
222
223 /* authz_core will log the require line and the result at DEBUG */
224 return AUTHZ_DENIED;
225}
226
227static authz_status
229 const char *require_line,
230 const void *parsed_require_line)
231{
232 const char *err = NULL;
234 const char *require, *t;
235 char *w;
236
237 /* the require line is an expression, which is evaluated now. */
238 require = ap_expr_str_exec(r, expr, &err);
239 if (err) {
241 "authz_host authorize: require forward-dns: "
242 "Can't evaluate require expression: %s", err);
243 return AUTHZ_DENIED;
244 }
245
246 /* tokenize expected list of names */
247 t = require;
248 while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
249
251 apr_status_t rv;
252 char *hash_ptr;
253
254 /* stop on apache configuration file comments */
255 if ((hash_ptr = ap_strchr(w, '#'))) {
256 if (hash_ptr == w) {
257 break;
258 }
259 *hash_ptr = '\0';
260 }
261
262 /* does the client ip match one of the names? */
263 rv = apr_sockaddr_info_get(&sa, w, APR_UNSPEC, 0, 0, r->pool);
264 if (rv == APR_SUCCESS) {
265
266 while (sa) {
268
270 "access check for %s as '%s': %s",
271 r->useragent_ip, w, match? "yes": "no");
272 if (match) {
273 return AUTHZ_GRANTED;
274 }
275
276 sa = sa->next;
277 }
278 }
279 else {
281 "No sockaddr info for \"%s\"", w);
282 }
283
284 /* stop processing, we are in a comment */
285 if (hash_ptr) {
286 break;
287 }
288 }
289
290 return AUTHZ_DENIED;
291}
292
310
311static const char *host_parse_config(cmd_parms *cmd, const char *require_line,
312 const void **parsed_require_line)
313{
314 const char *expr_err = NULL;
315 ap_expr_info_t *expr;
316
318 &expr_err, NULL);
319
320 if (expr_err)
321 return apr_pstrcat(cmd->temp_pool,
322 "Cannot parse expression in require line: ",
323 expr_err, NULL);
324
325 *parsed_require_line = expr;
326
327 return NULL;
328}
329
335
341
347
353
354
356 apr_pool_t *ptemp)
357{
358 /* we only use this hash in the parse config phase, ptemp is enough */
360
361 apr_ipsubnet_create(&localhost_v4, "127.0.0.0", "8", p);
363
364#if APR_HAVE_IPV6
367#endif
368
369 return OK;
370}
371
373 apr_pool_t *ptemp, server_rec *s)
374{
375 /* make sure we don't use this during .htaccess parsing */
377
378 return OK;
379}
380
400
402{
404 NULL, /* dir config creater */
405 NULL, /* dir merger --- default is to override */
406 NULL, /* server config */
407 NULL, /* merge server config */
408 NULL,
409 register_hooks /* register hooks */
410};
Symbol export macros and hook functions.
Apache Provider API.
int int const char ** match
Definition ap_regex.h:279
APR Hash Tables.
APR MD5 Routines.
APR Network library.
APR Strings library.
APR Standard Headers Support.
void ap_hook_post_config(ap_HOOK_post_config_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition config.c:105
#define AP_DECLARE_MODULE(foo)
void ap_hook_pre_config(ap_HOOK_pre_config_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition config.c:91
request_rec * r
#define OK
Definition httpd.h:456
#define APLOGNO(n)
Definition http_log.h:117
#define ap_log_rerror
Definition http_log.h:454
#define APLOG_ERR
Definition http_log.h:67
#define APLOG_MARK
Definition http_log.h:283
#define APLOG_WARNING
Definition http_log.h:68
#define APLOG_DEBUG
Definition http_log.h:71
apr_status_t ap_register_auth_provider(apr_pool_t *pool, const char *provider_group, const char *provider_name, const char *provider_version, const void *provider, int type)
Definition request.c:2179
#define AP_AUTH_INTERNAL_PER_CONF
unsigned int count
Definition apr_md5.h:152
#define APR_STATUS_IS_EINVAL(s)
Definition apr_errno.h:1266
const char * mask
Definition apr_date.h:60
#define APR_HOOK_MIDDLE
Definition apr_hooks.h:303
#define AP_EXPR_FLAG_STRING_RESULT
Definition ap_expr.h:68
#define ap_expr_parse_cmd(cmd, expr, flags, err, lookup_fn)
Definition ap_expr.h:340
const char * ap_expr_str_exec(request_rec *r, const ap_expr_info_t *expr, const char **err)
#define STANDARD20_MODULE_STUFF
#define ap_strchr(s, c)
Definition httpd.h:2351
#define ap_strchr_c(s, c)
Definition httpd.h:2353
char * ap_getword_conf(apr_pool_t *p, const char **line)
Definition util.c:833
apr_size_t size
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
int strcasecmp(const char *a, const char *b)
#define APR_HASH_KEY_STRING
Definition apr_hash.h:47
apr_sockaddr_t * addr
apr_sockaddr_t * sa
apr_interval_time_t t
#define APR_UNSPEC
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
const char * s
Definition apr_strings.h:95
apr_int32_t apr_int32_t apr_int32_t err
apr_cmdtype_e cmd
const char * ap_get_useragent_host(request_rec *req, int type, int *str_is_ip)
Definition core.c:1036
#define REMOTE_DOUBLE_REV
Definition http_core.h:118
Apache Configuration.
CORE HTTP Daemon.
Apache Logging library.
HTTP protocol handling.
Apache Request library.
HTTP Daemon routines.
apr_pool_t * p
Definition md_event.c:32
Authentication and Authorization Extension for Apache.
authz_status
Definition mod_auth.h:72
@ AUTHZ_DENIED
Definition mod_auth.h:73
@ AUTHZ_GRANTED
Definition mod_auth.h:74
#define AUTHZ_PROVIDER_VERSION
Definition mod_auth.h:42
#define AUTHZ_PROVIDER_GROUP
Definition mod_auth.h:40
static const char * ip_parse_config(cmd_parms *cmd, const char *require_line, const void **parsed_require_line)
static int authz_host_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
static authz_status ip_check_authorization(request_rec *r, const char *require_line, const void *parsed_require_line)
static apr_hash_t * parsed_subnets
static int in_domain(const char *domain, const char *what)
static int authz_host_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
static const authz_provider authz_local_provider
static authz_status host_check_authorization(request_rec *r, const char *require_line, const void *parsed_require_line)
static const authz_provider authz_forward_dns_provider
static authz_status forward_dns_check_authorization(request_rec *r, const char *require_line, const void *parsed_require_line)
static apr_ipsubnet_t * localhost_v4
static void register_hooks(apr_pool_t *p)
static const authz_provider authz_host_provider
static authz_status local_check_authorization(request_rec *r, const char *require_line, const void *parsed_require_line)
static const char * host_parse_config(cmd_parms *cmd, const char *require_line, const void **parsed_require_line)
static const authz_provider authz_ip_provider
return NULL
Definition mod_so.c:359
apr_sockaddr_t * next
apr_sockaddr_t * local_addr
Definition httpd.h:1162
A structure that represents the current request.
Definition httpd.h:845
char * uri
Definition httpd.h:1016
char * useragent_ip
Definition httpd.h:1101
apr_pool_t * pool
Definition httpd.h:847
apr_sockaddr_t * useragent_addr
Definition httpd.h:1100
conn_rec * connection
Definition httpd.h:849
A structure to keep track of authorization requirements.
Definition http_core.h:316
A structure to store information for each virtual server.
Definition httpd.h:1322