]> granicus.if.org Git - apache/blob - server/vhost.c
Add compiled and loaded PCRE version numbers
[apache] / server / vhost.c
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  * @file  vhost.c
19  * @brief functions pertaining to virtual host addresses
20  *        (configuration and run-time)
21  */
22
23 #include "apr.h"
24 #include "apr_strings.h"
25 #include "apr_lib.h"
26
27 #define APR_WANT_STRFUNC
28 #include "apr_want.h"
29
30 #include "ap_config.h"
31 #include "httpd.h"
32 #include "http_config.h"
33 #include "http_log.h"
34 #include "http_vhost.h"
35 #include "http_protocol.h"
36 #include "http_core.h"
37
38 #if APR_HAVE_ARPA_INET_H
39 #include <arpa/inet.h>
40 #endif
41
42 /* we know core's module_index is 0 */
43 #undef APLOG_MODULE_INDEX
44 #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
45
46 /*
47  * After all the definitions there's an explanation of how it's all put
48  * together.
49  */
50
51 /* meta-list of name-vhosts.  Each server_rec can be in possibly multiple
52  * lists of name-vhosts.
53  */
54 typedef struct name_chain name_chain;
55 struct name_chain {
56     name_chain *next;
57     server_addr_rec *sar;       /* the record causing it to be in
58                                  * this chain (needed for port comparisons) */
59     server_rec *server;         /* the server to use on a match */
60 };
61
62 /* meta-list of ip addresses.  Each server_rec can be in possibly multiple
63  * hash chains since it can have multiple ips.
64  */
65 typedef struct ipaddr_chain ipaddr_chain;
66 struct ipaddr_chain {
67     ipaddr_chain *next;
68     server_addr_rec *sar;       /* the record causing it to be in
69                                  * this chain (need for both ip addr and port
70                                  * comparisons) */
71     server_rec *server;         /* the server to use if this matches */
72     name_chain *names;          /* if non-NULL then a list of name-vhosts
73                                  * sharing this address */
74     name_chain *initialnames;   /* no runtime use, temporary storage of first
75                                  * NVH'es names */
76 };
77
78 /* This defines the size of the hash table used for hashing ip addresses
79  * of virtual hosts.  It must be a power of two.
80  */
81 #ifndef IPHASH_TABLE_SIZE
82 #define IPHASH_TABLE_SIZE 256
83 #endif
84
85 /* A (n) bucket hash table, each entry has a pointer to a server rec and
86  * a pointer to the other entries in that bucket.  Each individual address,
87  * even for virtualhosts with multiple addresses, has an entry in this hash
88  * table.  There are extra buckets for _default_, and name-vhost entries.
89  *
90  * Note that after config time this is constant, so it is thread-safe.
91  */
92 static ipaddr_chain *iphash_table[IPHASH_TABLE_SIZE];
93
94 /* dump out statistics about the hash function */
95 /* #define IPHASH_STATISTICS */
96
97 /* list of the _default_ servers */
98 static ipaddr_chain *default_list;
99
100 /* whether a config error was seen */
101 static int config_error = 0;
102
103 /* config check function */
104 static int vhost_check_config(apr_pool_t *p, apr_pool_t *plog,
105                               apr_pool_t *ptemp, server_rec *s);
106
107 /*
108  * How it's used:
109  *
110  * The ip address determines which chain in iphash_table is interesting, then
111  * a comparison is done down that chain to find the first ipaddr_chain whose
112  * sar matches the address:port pair.
113  *
114  * If that ipaddr_chain has names == NULL then you're done, it's an ip-vhost.
115  *
116  * Otherwise it's a name-vhost list, and the default is the server in the
117  * ipaddr_chain record.  We tuck away the ipaddr_chain record in the
118  * conn_rec field vhost_lookup_data.  Later on after the headers we get a
119  * second chance, and we use the name_chain to figure out what name-vhost
120  * matches the headers.
121  *
122  * If there was no ip address match in the iphash_table then do a lookup
123  * in the default_list.
124  *
125  * How it's put together ... well you should be able to figure that out
126  * from how it's used.  Or something like that.
127  */
128
129
130 /* called at the beginning of the config */
131 AP_DECLARE(void) ap_init_vhost_config(apr_pool_t *p)
132 {
133     memset(iphash_table, 0, sizeof(iphash_table));
134     default_list = NULL;
135     ap_hook_check_config(vhost_check_config, NULL, NULL, APR_HOOK_MIDDLE);
136 }
137
138
139 /*
140  * Parses a host of the form <address>[:port]
141  * paddr is used to create a list in the order of input
142  * **paddr is the ->next pointer of the last entry (or s->addrs)
143  * *paddr is the variable used to keep track of **paddr between calls
144  * port is the default port to assume
145  */
146 static const char *get_addresses(apr_pool_t *p, const char *w_,
147                                  server_addr_rec ***paddr,
148                                  apr_port_t default_port)
149 {
150     apr_sockaddr_t *my_addr;
151     server_addr_rec *sar;
152     char *w, *host, *scope_id;
153     int wild_port;
154     apr_size_t wlen;
155     apr_port_t port;
156     apr_status_t rv;
157
158     if (*w_ == '\0')
159         return NULL;
160
161     wlen = strlen(w_);                   /* wlen must be > 0 at this point */
162     w = apr_pstrmemdup(p, w_, wlen);
163     /* apr_parse_addr_port() doesn't understand ":*" so handle that first. */
164     wild_port = 0;
165     if (w[wlen - 1] == '*') {
166         if (wlen < 2) {
167             wild_port = 1;
168         }
169         else if (w[wlen - 2] == ':') {
170             w[wlen - 2] = '\0';
171             wild_port = 1;
172         }
173     }
174     rv = apr_parse_addr_port(&host, &scope_id, &port, w, p);
175     /* If the string is "80", apr_parse_addr_port() will be happy and set
176      * host to NULL and port to 80, so watch out for that.
177      */
178     if (rv != APR_SUCCESS) {
179         return "The address or port is invalid";
180     }
181     if (!host) {
182         return "Missing address for VirtualHost";
183     }
184     if (scope_id) {
185         return "Scope ids are not supported";
186     }
187     if (!port && !wild_port) {
188         port = default_port;
189     }
190
191     if (strcmp(host, "*") == 0 || strcasecmp(host, "_default_") == 0) {
192         rv = apr_sockaddr_info_get(&my_addr, NULL, APR_UNSPEC, port, 0, p);
193         if (rv) {
194             return "Could not determine a wildcard address ('0.0.0.0') -- "
195                 "check resolver configuration.";
196         }
197     }
198     else {
199         rv = apr_sockaddr_info_get(&my_addr, host, APR_UNSPEC, port, 0, p);
200         if (rv != APR_SUCCESS) {
201             ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, APLOGNO(00547)
202                 "Could not resolve host name %s -- ignoring!", host);
203             return NULL;
204         }
205     }
206
207     /* Remember all addresses for the host */
208
209     do {
210         sar = apr_pcalloc(p, sizeof(server_addr_rec));
211         **paddr = sar;
212         *paddr = &sar->next;
213         sar->host_addr = my_addr;
214         sar->host_port = port;
215         sar->virthost = host;
216         my_addr = my_addr->next;
217     } while (my_addr);
218
219     return NULL;
220 }
221
222
223 /* parse the <VirtualHost> addresses */
224 const char *ap_parse_vhost_addrs(apr_pool_t *p,
225                                  const char *hostname,
226                                  server_rec *s)
227 {
228     server_addr_rec **addrs;
229     const char *err;
230
231     /* start the list of addreses */
232     addrs = &s->addrs;
233     while (hostname[0]) {
234         err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
235         if (err) {
236             *addrs = NULL;
237             return err;
238         }
239     }
240     /* terminate the list */
241     *addrs = NULL;
242     if (s->addrs) {
243         if (s->addrs->host_port) {
244             /* override the default port which is inherited from main_server */
245             s->port = s->addrs->host_port;
246         }
247     }
248     return NULL;
249 }
250
251
252 AP_DECLARE_NONSTD(const char *)ap_set_name_virtual_host(cmd_parms *cmd,
253                                                         void *dummy,
254                                                         const char *arg)
255 {
256     static int warnonce = 0;
257     if (++warnonce == 1) {
258         ap_log_error(APLOG_MARK, APLOG_NOTICE|APLOG_STARTUP, APR_SUCCESS, NULL, APLOGNO(00548)
259                      "NameVirtualHost has no effect and will be removed in the "
260                      "next release %s:%d",
261                      cmd->directive->filename,
262                      cmd->directive->line_num);
263     }
264
265     return NULL;
266 }
267
268
269 /* hash table statistics, keep this in here for the beta period so
270  * we can find out if the hash function is ok
271  */
272 #ifdef IPHASH_STATISTICS
273 static int iphash_compare(const void *a, const void *b)
274 {
275     return (*(const int *) b - *(const int *) a);
276 }
277
278
279 static void dump_iphash_statistics(server_rec *main_s)
280 {
281     unsigned count[IPHASH_TABLE_SIZE];
282     int i;
283     ipaddr_chain *src;
284     unsigned total;
285     char buf[HUGE_STRING_LEN];
286     char *p;
287
288     total = 0;
289     for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
290         count[i] = 0;
291         for (src = iphash_table[i]; src; src = src->next) {
292             ++count[i];
293             if (i < IPHASH_TABLE_SIZE) {
294                 /* don't count the slop buckets in the total */
295                 ++total;
296             }
297         }
298     }
299     qsort(count, IPHASH_TABLE_SIZE, sizeof(count[0]), iphash_compare);
300     p = buf + apr_snprintf(buf, sizeof(buf),
301                            "iphash: total hashed = %u, avg chain = %u, "
302                            "chain lengths (count x len):",
303                            total, total / IPHASH_TABLE_SIZE);
304     total = 1;
305     for (i = 1; i < IPHASH_TABLE_SIZE; ++i) {
306         if (count[i - 1] != count[i]) {
307             p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
308                               total, count[i - 1]);
309             total = 1;
310         }
311         else {
312             ++total;
313         }
314     }
315     p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
316                       total, count[IPHASH_TABLE_SIZE - 1]);
317     ap_log_error(APLOG_MARK, APLOG_DEBUG, main_s, buf);
318 }
319 #endif
320
321
322 /* This hashing function is designed to get good distribution in the cases
323  * where the server is handling entire "networks" of servers.  i.e. a
324  * whack of /24s.  This is probably the most common configuration for
325  * ISPs with large virtual servers.
326  *
327  * NOTE: This function is symmetric (i.e. collapses all 4 octets
328  * into one), so machine byte order (big/little endianness) does not matter.
329  *
330  * Hash function provided by David Hankins.
331  */
332 static APR_INLINE unsigned hash_inaddr(unsigned key)
333 {
334     key ^= (key >> 16);
335     return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
336 }
337
338 static APR_INLINE unsigned hash_addr(struct apr_sockaddr_t *sa)
339 {
340     unsigned key;
341
342     /* The key is the last four bytes of the IP address.
343      * For IPv4, this is the entire address, as always.
344      * For IPv6, this is usually part of the MAC address.
345      */
346     key = *(unsigned *)((char *)sa->ipaddr_ptr + sa->ipaddr_len - 4);
347     return hash_inaddr(key);
348 }
349
350 static ipaddr_chain *new_ipaddr_chain(apr_pool_t *p,
351                                       server_rec *s, server_addr_rec *sar)
352 {
353     ipaddr_chain *new;
354
355     new = apr_palloc(p, sizeof(*new));
356     new->names = NULL;
357     new->initialnames = NULL;
358     new->server = s;
359     new->sar = sar;
360     new->next = NULL;
361     return new;
362 }
363
364
365 static name_chain *new_name_chain(apr_pool_t *p,
366                                   server_rec *s, server_addr_rec *sar)
367 {
368     name_chain *new;
369
370     new = apr_palloc(p, sizeof(*new));
371     new->server = s;
372     new->sar = sar;
373     new->next = NULL;
374     return new;
375 }
376
377
378 static APR_INLINE ipaddr_chain *find_ipaddr(apr_sockaddr_t *sa)
379 {
380     unsigned bucket;
381     ipaddr_chain *trav = NULL;
382     ipaddr_chain *wild_match = NULL;
383
384     /* scan the hash table for an exact match first */
385     bucket = hash_addr(sa);
386     for (trav = iphash_table[bucket]; trav; trav = trav->next) {
387         server_addr_rec *sar = trav->sar;
388         apr_sockaddr_t *cur = sar->host_addr;
389
390         if (cur->port == sa->port) {
391             if (apr_sockaddr_equal(cur, sa)) {
392                 return trav;
393             }
394         }
395         if (wild_match == NULL && (cur->port == 0 || sa->port == 0)) {
396             if (apr_sockaddr_equal(cur, sa)) {
397                 /* don't break, continue looking for an exact match */
398                 wild_match = trav;
399             }
400         }
401     }
402     return wild_match;
403 }
404
405 static ipaddr_chain *find_default_server(apr_port_t port)
406 {
407     server_addr_rec *sar;
408     ipaddr_chain *trav = NULL;
409     ipaddr_chain *wild_match = NULL;
410
411     for (trav = default_list; trav; trav = trav->next) {
412         sar = trav->sar;
413         if (sar->host_port == port) {
414             /* match! */
415             return trav;
416         }
417         if (wild_match == NULL && sar->host_port == 0) {
418             /* don't break, continue looking for an exact match */
419             wild_match = trav;
420         }
421     }
422     return wild_match;
423 }
424
425 #if APR_HAVE_IPV6
426 #define IS_IN6_ANYADDR(ad) ((ad)->family == APR_INET6                   \
427                             && IN6_IS_ADDR_UNSPECIFIED(&(ad)->sa.sin6.sin6_addr))
428 #else
429 #define IS_IN6_ANYADDR(ad) (0)
430 #endif
431
432 static void dump_a_vhost(apr_file_t *f, ipaddr_chain *ic)
433 {
434     name_chain *nc;
435     int len;
436     char buf[MAX_STRING_LEN];
437     apr_sockaddr_t *ha = ic->sar->host_addr;
438
439     if ((ha->family == APR_INET && ha->sa.sin.sin_addr.s_addr == INADDR_ANY)
440         || IS_IN6_ANYADDR(ha)) {
441         len = apr_snprintf(buf, sizeof(buf), "*:%u",
442                            ic->sar->host_port);
443     }
444     else {
445         len = apr_snprintf(buf, sizeof(buf), "%pI", ha);
446     }
447     if (ic->sar->host_port == 0) {
448         buf[len-1] = '*';
449     }
450     if (ic->names == NULL) {
451         apr_file_printf(f, "%-22s %s (%s:%u)\n", buf,
452                         ic->server->server_hostname,
453                         ic->server->defn_name, ic->server->defn_line_number);
454         return;
455     }
456     apr_file_printf(f, "%-22s is a NameVirtualHost\n"
457                     "%8s default server %s (%s:%u)\n",
458                     buf, "", ic->server->server_hostname,
459                     ic->server->defn_name, ic->server->defn_line_number);
460     for (nc = ic->names; nc; nc = nc->next) {
461         if (nc->sar->host_port) {
462             apr_file_printf(f, "%8s port %u ", "", nc->sar->host_port);
463         }
464         else {
465             apr_file_printf(f, "%8s port * ", "");
466         }
467         apr_file_printf(f, "namevhost %s (%s:%u)\n",
468                         nc->server->server_hostname,
469                         nc->server->defn_name, nc->server->defn_line_number);
470         if (nc->server->names) {
471             apr_array_header_t *names = nc->server->names;
472             char **name = (char **)names->elts;
473             int i;
474             for (i = 0; i < names->nelts; ++i) {
475                 if (name[i]) {
476                     apr_file_printf(f, "%16s alias %s\n", "", name[i]);
477                 }
478             }
479         }
480         if (nc->server->wild_names) {
481             apr_array_header_t *names = nc->server->wild_names;
482             char **name = (char **)names->elts;
483             int i;
484             for (i = 0; i < names->nelts; ++i) {
485                 if (name[i]) {
486                     apr_file_printf(f, "%16s wild alias %s\n", "", name[i]);
487                 }
488             }
489         }
490     }
491 }
492
493 static void dump_vhost_config(apr_file_t *f)
494 {
495     ipaddr_chain *ic;
496     int i;
497
498     apr_file_printf(f, "VirtualHost configuration:\n");
499
500     /* non-wildcard servers */
501     for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
502         for (ic = iphash_table[i]; ic; ic = ic->next) {
503             dump_a_vhost(f, ic);
504         }
505     }
506
507     /* wildcard servers */
508     for (ic = default_list; ic; ic = ic->next) {
509         dump_a_vhost(f, ic);
510     }
511 }
512
513
514 /*
515  * When a second or later virtual host maps to the same IP chain,
516  * add the relevant server names to the chain.  Special care is taken
517  * to avoid adding ic->names until we're sure there are multiple VH'es.
518  */
519 static void add_name_vhost_config(apr_pool_t *p, server_rec *main_s,
520                                  server_rec *s, server_addr_rec *sar,
521                                  ipaddr_chain *ic)
522 {
523
524    name_chain *nc = new_name_chain(p, s, sar);
525    nc->next = ic->names;
526
527    /* iterating backwards, so each one we see becomes the current default server */
528    ic->server = s;
529
530    if (ic->names == NULL) {
531        if (ic->initialnames == NULL) {
532            /* first pass, set these names aside in case we see another VH.
533             * Until then, this looks like an IP-based VH to runtime.
534             */
535            ic->initialnames = nc;
536        }
537        else {
538            /* second pass through this chain -- this really is an NVH, and we
539             * have two sets of names to link in.
540             */
541            nc->next = ic->initialnames;
542            ic->names = nc;
543            ic->initialnames = NULL;
544        }
545    }
546    else {
547        /* 3rd or more -- just keep stacking the names */
548        ic->names = nc;
549    }
550 }
551
552 /* compile the tables and such we need to do the run-time vhost lookups */
553 AP_DECLARE(void) ap_fini_vhost_config(apr_pool_t *p, server_rec *main_s)
554 {
555     server_addr_rec *sar;
556     int has_default_vhost_addr;
557     server_rec *s;
558     int i;
559     ipaddr_chain **iphash_table_tail[IPHASH_TABLE_SIZE];
560
561     /* Main host first */
562     s = main_s;
563
564     if (!s->server_hostname) {
565         s->server_hostname = ap_get_local_host(p);
566     }
567
568     /* initialize the tails */
569     for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
570         iphash_table_tail[i] = &iphash_table[i];
571     }
572
573     /* The next things to go into the hash table are the virtual hosts
574      * themselves.  They're listed off of main_s->next in the reverse
575      * order they occured in the config file, so we insert them at
576      * the iphash_table_tail but don't advance the tail.
577      */
578
579     for (s = main_s->next; s; s = s->next) {
580         server_addr_rec *sar_prev = NULL;
581         has_default_vhost_addr = 0;
582         for (sar = s->addrs; sar; sar = sar->next) {
583             ipaddr_chain *ic;
584             char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */
585             /* XXX: this treats 0.0.0.0 as a "default" server which matches no-exact-match for IPv6 */
586             if (!memcmp(sar->host_addr->ipaddr_ptr, inaddr_any, sar->host_addr->ipaddr_len)) {
587                 ic = find_default_server(sar->host_port);
588
589                 if (ic && sar->host_port == ic->sar->host_port) { /* we're a match for an existing "default server"  */
590                     if (!sar_prev || memcmp(sar_prev->host_addr->ipaddr_ptr, inaddr_any, sar_prev->host_addr->ipaddr_len)
591                                   || sar_prev->host_port != sar->host_port) { 
592                         add_name_vhost_config(p, main_s, s, sar, ic);
593                     }
594                 }
595                 else { 
596                     /* No default server, or we found a default server but
597                     ** exactly one of us is a wildcard port, which means we want
598                     ** two ip-based vhosts not an NVH with two names
599                     */
600                     ic = new_ipaddr_chain(p, s, sar);
601                     ic->next = default_list;
602                     default_list = ic;
603                     add_name_vhost_config(p, main_s, s, sar, ic);
604                 }
605                 has_default_vhost_addr = 1;
606             }
607             else {
608                 /* see if it matches something we've already got */
609                 ic = find_ipaddr(sar->host_addr);
610
611                 if (!ic || sar->host_port != ic->sar->host_port) {
612                     /* No matching server, or we found a matching server but
613                     ** exactly one of us is a wildcard port, which means we want
614                     ** two ip-based vhosts not an NVH with two names
615                     */
616                     unsigned bucket = hash_addr(sar->host_addr);
617                     ic = new_ipaddr_chain(p, s, sar);
618                     ic->next = *iphash_table_tail[bucket];
619                     *iphash_table_tail[bucket] = ic;
620                 }
621                 add_name_vhost_config(p, main_s, s, sar, ic);
622             }
623             sar_prev = sar;
624         }
625
626         /* Ok now we want to set up a server_hostname if the user was
627          * silly enough to forget one.
628          * XXX: This is silly we should just crash and burn.
629          */
630         if (!s->server_hostname) {
631             if (has_default_vhost_addr) {
632                 s->server_hostname = main_s->server_hostname;
633             }
634             else if (!s->addrs) {
635                 /* what else can we do?  at this point this vhost has
636                     no configured name, probably because they used
637                     DNS in the VirtualHost statement.  It's disabled
638                     anyhow by the host matching code.  -djg */
639                 s->server_hostname =
640                     apr_pstrdup(p, "bogus_host_without_forward_dns");
641             }
642             else {
643                 apr_status_t rv;
644                 char *hostname;
645
646                 rv = apr_getnameinfo(&hostname, s->addrs->host_addr, 0);
647                 if (rv == APR_SUCCESS) {
648                     s->server_hostname = apr_pstrdup(p, hostname);
649                 }
650                 else {
651                     /* again, what can we do?  They didn't specify a
652                        ServerName, and their DNS isn't working. -djg */
653                     char *ipaddr_str;
654
655                     apr_sockaddr_ip_get(&ipaddr_str, s->addrs->host_addr);
656                     ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_s, APLOGNO(00549)
657                                  "Failed to resolve server name "
658                                  "for %s (check DNS) -- or specify an explicit "
659                                  "ServerName",
660                                  ipaddr_str);
661                     s->server_hostname =
662                         apr_pstrdup(p, "bogus_host_without_reverse_dns");
663                 }
664             }
665         }
666     }
667
668 #ifdef IPHASH_STATISTICS
669     dump_iphash_statistics(main_s);
670 #endif
671     if (ap_exists_config_define("DUMP_VHOSTS")) {
672         apr_file_t *thefile = NULL;
673         apr_file_open_stdout(&thefile, p);
674         dump_vhost_config(thefile);
675     }
676 }
677
678 static int vhost_check_config(apr_pool_t *p, apr_pool_t *plog,
679                               apr_pool_t *ptemp, server_rec *s)
680 {
681     return config_error ? !OK : OK;
682 }
683
684 /*****************************************************************************
685  * run-time vhost matching functions
686  */
687
688 static apr_status_t fix_hostname_v6_literal(request_rec *r, char *host)
689 {
690     char *dst;
691     int double_colon = 0;
692
693     for (dst = host; *dst; dst++) {
694         if (apr_isxdigit(*dst)) {
695             if (apr_isupper(*dst)) {
696                 *dst = apr_tolower(*dst);
697             }
698         }
699         else if (*dst == ':') {
700             if (*(dst + 1) == ':') {
701                 if (double_colon)
702                     return APR_EINVAL;
703                 double_colon = 1;
704             }
705             else if (*(dst + 1) == '.') {
706                 return APR_EINVAL;
707             }
708         }
709         else if (*dst == '.') {
710             /* For IPv4-mapped IPv6 addresses like ::FFFF:129.144.52.38 */
711             if (*(dst + 1) == ':' || *(dst + 1) == '.')
712                 return APR_EINVAL;
713         }
714         else {
715             return APR_EINVAL;
716         }
717     }
718     return APR_SUCCESS;
719 }
720
721 static apr_status_t fix_hostname_non_v6(request_rec *r, char *host)
722 {
723     char *dst;
724
725     for (dst = host; *dst; dst++) {
726         if (apr_islower(*dst)) {
727             /* leave char unchanged */
728         }
729         else if (*dst == '.') {
730             if (*(dst + 1) == '.') {
731                 return APR_EINVAL;
732             }
733         }
734         else if (apr_isupper(*dst)) {
735             *dst = apr_tolower(*dst);
736         }
737         else if (*dst == '/' || *dst == '\\') {
738             return APR_EINVAL;
739         }
740     }
741     /* strip trailing gubbins */
742     if (dst > host && dst[-1] == '.') {
743         dst[-1] = '\0';
744     }
745     return APR_SUCCESS;
746 }
747
748 /*
749  * If strict mode ever becomes the default, this should be folded into
750  * fix_hostname_non_v6()
751  */
752 static apr_status_t strict_hostname_check(request_rec *r, char *host,
753                                           int logonly)
754 {
755     char *ch;
756     int is_dotted_decimal = 1, leading_zeroes = 0, dots = 0;
757
758     for (ch = host; *ch; ch++) {
759         if (!apr_isascii(*ch)) {
760             goto bad;
761         }
762         else if (apr_isalpha(*ch) || *ch == '-') {
763             is_dotted_decimal = 0;
764         }
765         else if (ch[0] == '.') {
766             dots++;
767             if (ch[1] == '0' && apr_isdigit(ch[2]))
768                 leading_zeroes = 1;
769         }
770         else if (!apr_isdigit(*ch)) {
771            /* also takes care of multiple Host headers by denying commas */
772             goto bad;
773         }
774     }
775     if (is_dotted_decimal) {
776         if (host[0] == '.' || (host[0] == '0' && apr_isdigit(host[1])))
777             leading_zeroes = 1;
778         if (leading_zeroes || dots != 3) {
779             /* RFC 3986 7.4 */
780             goto bad;
781         }
782     }
783     else {
784         /* The top-level domain must start with a letter (RFC 1123 2.1) */
785         while (ch > host && *ch != '.')
786             ch--;
787         if (ch[0] == '.' && ch[1] != '\0' && !apr_isalpha(ch[1]))
788             goto bad;
789     }
790     return APR_SUCCESS;
791
792 bad:
793     ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02415)
794                   "[strict] Invalid host name '%s'%s%.6s",
795                   host, *ch ? ", problem near: " : "", ch);
796     if (logonly)
797         return APR_SUCCESS;
798     return APR_EINVAL;
799 }
800
801 /* Lowercase and remove any trailing dot and/or :port from the hostname,
802  * and check that it is sane.
803  *
804  * In most configurations the exact syntax of the hostname isn't
805  * important so strict sanity checking isn't necessary. However, in
806  * mass hosting setups (using mod_vhost_alias or mod_rewrite) where
807  * the hostname is interpolated into the filename, we need to be sure
808  * that the interpolation doesn't expose parts of the filesystem.
809  * We don't do strict RFC 952 / RFC 1123 syntax checking in order
810  * to support iDNS and people who erroneously use underscores.
811  * Instead we just check for filesystem metacharacters: directory
812  * separators / and \ and sequences of more than one dot.
813  */
814 static int fix_hostname(request_rec *r, const char *host_header,
815                         unsigned http_conformance)
816 {
817     const char *src;
818     char *host, *scope_id;
819     apr_port_t port;
820     apr_status_t rv;
821     const char *c;
822     int is_v6literal = 0;
823     int strict = http_conformance & AP_HTTP_CONFORMANCE_STRICT;
824     int strict_logonly = http_conformance & AP_HTTP_CONFORMANCE_LOGONLY;
825
826     src = host_header ? host_header : r->hostname;
827
828     /* According to RFC 2616, Host header field CAN be blank */
829     if (!*src) {
830         return is_v6literal;
831     }
832
833     /* apr_parse_addr_port will interpret a bare integer as a port
834      * which is incorrect in this context.  So treat it separately.
835      */
836     for (c = src; apr_isdigit(*c); ++c);
837     if (!*c) {
838         /* pure integer */
839         if (strict) {
840             /* RFC 3986 7.4 */
841             ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02416)
842                          "[strict] purely numeric host names not allowed: %s",
843                          src);
844             if (!strict_logonly)
845                 goto bad_nolog;
846         }
847         r->hostname = src;
848         return is_v6literal;
849     }
850
851     if (host_header) {
852         rv = apr_parse_addr_port(&host, &scope_id, &port, src, r->pool);
853         if (rv != APR_SUCCESS || scope_id)
854             goto bad;
855         if (port) {
856             /* Don't throw the Host: header's port number away:
857                save it in parsed_uri -- ap_get_server_port() needs it! */
858             /* @@@ XXX there should be a better way to pass the port.
859              *         Like r->hostname, there should be a r->portno
860              */
861             r->parsed_uri.port = port;
862             r->parsed_uri.port_str = apr_itoa(r->pool, (int)port);
863         }
864         if (host_header[0] == '[')
865             is_v6literal = 1;
866     }
867     else {
868         /*
869          * Already parsed, surrounding [ ] (if IPv6 literal) and :port have
870          * already been removed.
871          */
872         host = apr_pstrdup(r->pool, r->hostname);
873         if (ap_strchr(host, ':') != NULL)
874             is_v6literal = 1;
875     }
876
877     if (is_v6literal) {
878         rv = fix_hostname_v6_literal(r, host);
879     }
880     else {
881         rv = fix_hostname_non_v6(r, host);
882         if (strict && rv == APR_SUCCESS)
883             rv = strict_hostname_check(r, host, strict_logonly);
884     }
885     if (rv != APR_SUCCESS)
886         goto bad;
887
888     r->hostname = host;
889     return is_v6literal;
890
891 bad:
892     ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00550)
893                   "Client sent malformed Host header: %s",
894                   src);
895 bad_nolog:
896     r->status = HTTP_BAD_REQUEST;
897     return is_v6literal;
898 }
899
900 /* return 1 if host matches ServerName or ServerAliases */
901 static int matches_aliases(server_rec *s, const char *host)
902 {
903     int i;
904     apr_array_header_t *names;
905
906     /* match ServerName */
907     if (!strcasecmp(host, s->server_hostname)) {
908         return 1;
909     }
910
911     /* search all the aliases from ServerAlias directive */
912     names = s->names;
913     if (names) {
914         char **name = (char **) names->elts;
915         for (i = 0; i < names->nelts; ++i) {
916             if(!name[i]) continue;
917             if (!strcasecmp(host, name[i]))
918                 return 1;
919         }
920     }
921     names = s->wild_names;
922     if (names) {
923         char **name = (char **) names->elts;
924         for (i = 0; i < names->nelts; ++i) {
925             if(!name[i]) continue;
926             if (!ap_strcasecmp_match(host, name[i]))
927                 return 1;
928         }
929     }
930     return 0;
931 }
932
933
934 /* Suppose a request came in on the same socket as this r, and included
935  * a header "Host: host:port", would it map to r->server?  It's more
936  * than just that though.  When we do the normal matches for each request
937  * we don't even bother considering Host: etc on non-namevirtualhosts,
938  * we just call it a match.  But here we require the host:port to match
939  * the ServerName and/or ServerAliases.
940  */
941 AP_DECLARE(int) ap_matches_request_vhost(request_rec *r, const char *host,
942                                          apr_port_t port)
943 {
944     server_rec *s;
945     server_addr_rec *sar;
946
947     s = r->server;
948
949     /* search all the <VirtualHost> values */
950     /* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing
951      * consider:
952      *
953      *     NameVirtualHost 10.1.1.1
954      *     <VirtualHost 10.1.1.1>
955      *     ServerName v1
956      *     </VirtualHost>
957      *     <VirtualHost 10.1.1.1>
958      *     ServerName v2
959      *     </VirtualHost>
960      *
961      * Suppose r->server is v2, and we're asked to match "10.1.1.1".  We'll say
962      * "yup it's v2", when really it isn't... if a request came in for 10.1.1.1
963      * it would really go to v1.
964      */
965     for (sar = s->addrs; sar; sar = sar->next) {
966         if ((sar->host_port == 0 || port == sar->host_port)
967             && !strcasecmp(host, sar->virthost)) {
968             return 1;
969         }
970     }
971
972     /* the Port has to match now, because the rest don't have ports associated
973      * with them. */
974     if (port != s->port) {
975         return 0;
976     }
977
978     return matches_aliases(s, host);
979 }
980
981
982 static void check_hostalias(request_rec *r)
983 {
984     /*
985      * Even if the request has a Host: header containing a port we ignore
986      * that port.  We always use the physical port of the socket.  There
987      * are a few reasons for this:
988      *
989      * - the default of 80 or 443 for SSL is easier to handle this way
990      * - there is less of a possibility of a security problem
991      * - it simplifies the data structure
992      * - the client may have no idea that a proxy somewhere along the way
993      *   translated the request to another ip:port
994      * - except for the addresses from the VirtualHost line, none of the other
995      *   names we'll match have ports associated with them
996      */
997     const char *host = r->hostname;
998     apr_port_t port;
999     server_rec *s;
1000     server_rec *virthost_s;
1001     server_rec *last_s;
1002     name_chain *src;
1003
1004     virthost_s = NULL;
1005     last_s = NULL;
1006
1007     port = r->connection->local_addr->port;
1008
1009     /* Recall that the name_chain is a list of server_addr_recs, some of
1010      * whose ports may not match.  Also each server may appear more than
1011      * once in the chain -- specifically, it will appear once for each
1012      * address from its VirtualHost line which matched.  We only want to
1013      * do the full ServerName/ServerAlias comparisons once for each
1014      * server, fortunately we know that all the VirtualHost addresses for
1015      * a single server are adjacent to each other.
1016      */
1017
1018     for (src = r->connection->vhost_lookup_data; src; src = src->next) {
1019         server_addr_rec *sar;
1020
1021         /* We only consider addresses on the name_chain which have a matching
1022          * port
1023          */
1024         sar = src->sar;
1025         if (sar->host_port != 0 && port != sar->host_port) {
1026             continue;
1027         }
1028
1029         s = src->server;
1030
1031         /* If we still need to do ServerName and ServerAlias checks for this
1032          * server, do them now.
1033          */
1034         if (s != last_s) {
1035             /* does it match any ServerName or ServerAlias directive? */
1036             if (matches_aliases(s, host)) {
1037                 goto found;
1038             }
1039         }
1040         last_s = s;
1041
1042         /* Fallback: does it match the virthost from the sar? */
1043         if (!strcasecmp(host, sar->virthost)) {
1044             /* only the first match is used */
1045             if (virthost_s == NULL) {
1046                 virthost_s = s;
1047             }
1048         }
1049     }
1050
1051     /* If ServerName and ServerAlias check failed, we end up here.  If it
1052      * matches a VirtualHost, virthost_s is set. Use that as fallback
1053      */
1054     if (virthost_s) {
1055         s = virthost_s;
1056         goto found;
1057     }
1058
1059     return;
1060
1061 found:
1062     /* s is the first matching server, we're done */
1063     r->server = s;
1064 }
1065
1066
1067 static void check_serverpath(request_rec *r)
1068 {
1069     server_rec *s;
1070     server_rec *last_s;
1071     name_chain *src;
1072     apr_port_t port;
1073
1074     port = r->connection->local_addr->port;
1075
1076     /*
1077      * This is in conjunction with the ServerPath code in http_core, so we
1078      * get the right host attached to a non- Host-sending request.
1079      *
1080      * See the comment in check_hostalias about how each vhost can be
1081      * listed multiple times.
1082      */
1083
1084     last_s = NULL;
1085     for (src = r->connection->vhost_lookup_data; src; src = src->next) {
1086         /* We only consider addresses on the name_chain which have a matching
1087          * port
1088          */
1089         if (src->sar->host_port != 0 && port != src->sar->host_port) {
1090             continue;
1091         }
1092
1093         s = src->server;
1094         if (s == last_s) {
1095             continue;
1096         }
1097         last_s = s;
1098
1099         if (s->path && !strncmp(r->uri, s->path, s->pathlen) &&
1100             (s->path[s->pathlen - 1] == '/' ||
1101              r->uri[s->pathlen] == '/' ||
1102              r->uri[s->pathlen] == '\0')) {
1103             r->server = s;
1104             return;
1105         }
1106     }
1107 }
1108
1109 static APR_INLINE const char *construct_host_header(request_rec *r,
1110                                                     int is_v6literal)
1111 {
1112     struct iovec iov[5];
1113     apr_size_t nvec = 0;
1114     /*
1115      * We cannot use ap_get_server_name/port here, because we must
1116      * ignore UseCanonicalName/Port.
1117      */
1118     if (is_v6literal) {
1119         iov[nvec].iov_base = "[";
1120         iov[nvec].iov_len = 1;
1121         nvec++;
1122     }
1123     iov[nvec].iov_base = (void *)r->hostname;
1124     iov[nvec].iov_len = strlen(r->hostname);
1125     nvec++;
1126     if (is_v6literal) {
1127         iov[nvec].iov_base = "]";
1128         iov[nvec].iov_len = 1;
1129         nvec++;
1130     }
1131     if (r->parsed_uri.port_str) {
1132         iov[nvec].iov_base = ":";
1133         iov[nvec].iov_len = 1;
1134         nvec++;
1135         iov[nvec].iov_base = r->parsed_uri.port_str;
1136         iov[nvec].iov_len = strlen(r->parsed_uri.port_str);
1137         nvec++;
1138     }
1139     return apr_pstrcatv(r->pool, iov, nvec, NULL);
1140 }
1141
1142 AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r)
1143 {
1144     core_server_config *conf = ap_get_core_module_config(r->server->module_config);
1145     const char *host_header = apr_table_get(r->headers_in, "Host");
1146     int is_v6literal = 0;
1147     int have_hostname_from_url = 0;
1148
1149     if (r->hostname) {
1150         /*
1151          * If there was a host part in the Request-URI, ignore the 'Host'
1152          * header.
1153          */
1154         have_hostname_from_url = 1;
1155         is_v6literal = fix_hostname(r, NULL, conf->http_conformance);
1156     }
1157     else if (host_header != NULL) {
1158         is_v6literal = fix_hostname(r, host_header, conf->http_conformance);
1159     }
1160     if (r->status != HTTP_OK)
1161         return;
1162
1163     if (conf->http_conformance & AP_HTTP_CONFORMANCE_STRICT) {
1164         /*
1165          * If we have both hostname from an absoluteURI and a Host header,
1166          * we must ignore the Host header (RFC 2616 5.2).
1167          * To enforce this, we reset the Host header to the value from the
1168          * request line.
1169          */
1170         if (have_hostname_from_url && host_header != NULL) {
1171             const char *info = "Would replace";
1172             const char *new = construct_host_header(r, is_v6literal);
1173             if (!(conf->http_conformance & AP_HTTP_CONFORMANCE_LOGONLY)) {
1174                 apr_table_set(r->headers_in, "Host", r->hostname);
1175                 info = "Replacing";
1176             }
1177             ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02417)
1178                           "%s Host header '%s' with host from request uri: "
1179                           "'%s'", info, host_header, new);
1180         }
1181     }
1182
1183     /* check if we tucked away a name_chain */
1184     if (r->connection->vhost_lookup_data) {
1185         if (r->hostname)
1186             check_hostalias(r);
1187         else
1188             check_serverpath(r);
1189     }
1190 }
1191
1192 /**
1193  * For every virtual host on this connection, call func_cb.
1194  */
1195 AP_DECLARE(int) ap_vhost_iterate_given_conn(conn_rec *conn,
1196                                             ap_vhost_iterate_conn_cb func_cb,
1197                                             void* baton)
1198 {
1199     server_rec *s;
1200     server_rec *last_s;
1201     name_chain *src;
1202     apr_port_t port;
1203     int rv = 0;
1204
1205     if (conn->vhost_lookup_data) {
1206         last_s = NULL;
1207         port = conn->local_addr->port;
1208
1209         for (src = conn->vhost_lookup_data; src; src = src->next) {
1210             server_addr_rec *sar;
1211
1212             /* We only consider addresses on the name_chain which have a
1213              * matching port.
1214              */
1215             sar = src->sar;
1216             if (sar->host_port != 0 && port != sar->host_port) {
1217                 continue;
1218             }
1219
1220             s = src->server;
1221
1222             if (s == last_s) {
1223                 /* we've already done a callback for this vhost. */
1224                 continue;
1225             }
1226
1227             last_s = s;
1228
1229             rv = func_cb(baton, conn, s);
1230
1231             if (rv != 0) {
1232                 break;
1233             }
1234         }
1235     }
1236     else {
1237         rv = func_cb(baton, conn, conn->base_server);
1238     }
1239
1240     return rv;
1241 }
1242
1243 /* Called for a new connection which has a known local_addr.  Note that the
1244  * new connection is assumed to have conn->server == main server.
1245  */
1246 AP_DECLARE(void) ap_update_vhost_given_ip(conn_rec *conn)
1247 {
1248     ipaddr_chain *trav;
1249     apr_port_t port;
1250
1251     /* scan the hash table for an exact match first */
1252     trav = find_ipaddr(conn->local_addr);
1253
1254     if (trav) {
1255         /* save the name_chain for later in case this is a name-vhost */
1256         conn->vhost_lookup_data = trav->names;
1257         conn->base_server = trav->server;
1258         return;
1259     }
1260
1261     /* maybe there's a default server or wildcard name-based vhost
1262      * matching this port
1263      */
1264     port = conn->local_addr->port;
1265
1266     trav = find_default_server(port);
1267     if (trav) {
1268         conn->vhost_lookup_data = trav->names;
1269         conn->base_server = trav->server;
1270         return;
1271     }
1272
1273     /* otherwise we're stuck with just the main server
1274      * and no name-based vhosts
1275      */
1276     conn->vhost_lookup_data = NULL;
1277 }