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 */ 54typedef struct name_chain name_chain; 55struct 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 */ 65typedef struct ipaddr_chain ipaddr_chain; 66struct 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 */ 92static 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 */ 98static ipaddr_chain *default_list; 99 100/* whether a config error was seen */ 101static int config_error = 0; 102 103/* config check function */ 104static 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 */ 131AP_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 */ 146static 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 */ 224const 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 252AP_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 273static int iphash_compare(const void *a, const void *b) 274{ 275 return (*(const int *) b - *(const int *) a); 276} 277 278 279static 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 */ 332static APR_INLINE unsigned hash_inaddr(unsigned key) 333{ 334 key ^= (key >> 16); 335 return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE; 336} 337 338static 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 350static 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 365static 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 378static 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 405static 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 432static 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 493static 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 */ 519static 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 */ 553AP_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 678static 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/* Lowercase and remove any trailing dot and/or :port from the hostname, 689 * and check that it is sane. 690 * 691 * In most configurations the exact syntax of the hostname isn't 692 * important so strict sanity checking isn't necessary. However, in 693 * mass hosting setups (using mod_vhost_alias or mod_rewrite) where 694 * the hostname is interpolated into the filename, we need to be sure 695 * that the interpolation doesn't expose parts of the filesystem. 696 * We don't do strict RFC 952 / RFC 1123 syntax checking in order 697 * to support iDNS and people who erroneously use underscores. 698 * Instead we just check for filesystem metacharacters: directory 699 * separators / and \ and sequences of more than one dot. 700 */ 701static void fix_hostname(request_rec *r) 702{ 703 char *host, *scope_id; 704 char *dst; 705 apr_port_t port; 706 apr_status_t rv; 707 const char *c; 708 709 /* According to RFC 2616, Host header field CAN be blank. */ 710 if (!*r->hostname) { 711 return; 712 } 713 714 /* apr_parse_addr_port will interpret a bare integer as a port 715 * which is incorrect in this context. So treat it separately. 716 */ 717 for (c = r->hostname; apr_isdigit(*c); ++c); 718 if (!*c) { /* pure integer */ 719 return; 720 } 721 722 rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool); 723 if (rv != APR_SUCCESS || scope_id) { 724 goto bad; 725 } 726 727 if (port) { 728 /* Don't throw the Host: header's port number away: 729 save it in parsed_uri -- ap_get_server_port() needs it! */ 730 /* @@@ XXX there should be a better way to pass the port. 731 * Like r->hostname, there should be a r->portno 732 */ 733 r->parsed_uri.port = port; 734 r->parsed_uri.port_str = apr_itoa(r->pool, (int)port); 735 } 736 737 /* if the hostname is an IPv6 numeric address string, it was validated 738 * already; otherwise, further validation is needed 739 */ 740 if (r->hostname[0] != '[') { 741 for (dst = host; *dst; dst++) { 742 if (apr_islower(*dst)) { 743 /* leave char unchanged */ 744 } 745 else if (*dst == '.') { 746 if (*(dst + 1) == '.') { 747 goto bad; 748 } 749 } 750 else if (apr_isupper(*dst)) { 751 *dst = apr_tolower(*dst); 752 } 753 else if (*dst == '/' || *dst == '\\') { 754 goto bad; 755 } 756 } 757 /* strip trailing gubbins */ 758 if (dst > host && dst[-1] == '.') { 759 dst[-1] = '\0'; 760 } 761 } 762 r->hostname = host; 763 return; 764 765bad: 766 r->status = HTTP_BAD_REQUEST; 767 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00550) 768 "Client sent malformed Host header: %s", 769 r->hostname); 770 return; 771} 772 773 774/* return 1 if host matches ServerName or ServerAliases */ 775static int matches_aliases(server_rec *s, const char *host) 776{ 777 int i; 778 apr_array_header_t *names; 779 780 /* match ServerName */ 781 if (!strcasecmp(host, s->server_hostname)) { 782 return 1; 783 } 784 785 /* search all the aliases from ServerAlias directive */ 786 names = s->names; 787 if (names) { 788 char **name = (char **) names->elts; 789 for (i = 0; i < names->nelts; ++i) { 790 if(!name[i]) continue; 791 if (!strcasecmp(host, name[i])) 792 return 1; 793 } 794 } 795 names = s->wild_names; 796 if (names) { 797 char **name = (char **) names->elts; 798 for (i = 0; i < names->nelts; ++i) { 799 if(!name[i]) continue; 800 if (!ap_strcasecmp_match(host, name[i])) 801 return 1; 802 } 803 } 804 return 0; 805} 806 807 808/* Suppose a request came in on the same socket as this r, and included 809 * a header "Host: host:port", would it map to r->server? It's more 810 * than just that though. When we do the normal matches for each request 811 * we don't even bother considering Host: etc on non-namevirtualhosts, 812 * we just call it a match. But here we require the host:port to match 813 * the ServerName and/or ServerAliases. 814 */ 815AP_DECLARE(int) ap_matches_request_vhost(request_rec *r, const char *host, 816 apr_port_t port) 817{ 818 server_rec *s; 819 server_addr_rec *sar; 820 821 s = r->server; 822 823 /* search all the <VirtualHost> values */ 824 /* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing 825 * consider: 826 * 827 * NameVirtualHost 10.1.1.1 828 * <VirtualHost 10.1.1.1> 829 * ServerName v1 830 * </VirtualHost> 831 * <VirtualHost 10.1.1.1> 832 * ServerName v2 833 * </VirtualHost> 834 * 835 * Suppose r->server is v2, and we're asked to match "10.1.1.1". We'll say 836 * "yup it's v2", when really it isn't... if a request came in for 10.1.1.1 837 * it would really go to v1. 838 */ 839 for (sar = s->addrs; sar; sar = sar->next) { 840 if ((sar->host_port == 0 || port == sar->host_port) 841 && !strcasecmp(host, sar->virthost)) { 842 return 1; 843 } 844 } 845 846 /* the Port has to match now, because the rest don't have ports associated 847 * with them. */ 848 if (port != s->port) { 849 return 0; 850 } 851 852 return matches_aliases(s, host); 853} 854 855 856static void check_hostalias(request_rec *r) 857{ 858 /* 859 * Even if the request has a Host: header containing a port we ignore 860 * that port. We always use the physical port of the socket. There 861 * are a few reasons for this: 862 * 863 * - the default of 80 or 443 for SSL is easier to handle this way 864 * - there is less of a possibility of a security problem 865 * - it simplifies the data structure 866 * - the client may have no idea that a proxy somewhere along the way 867 * translated the request to another ip:port 868 * - except for the addresses from the VirtualHost line, none of the other 869 * names we'll match have ports associated with them 870 */ 871 const char *host = r->hostname; 872 apr_port_t port; 873 server_rec *s; 874 server_rec *virthost_s; 875 server_rec *last_s; 876 name_chain *src; 877 878 virthost_s = NULL; 879 last_s = NULL; 880 881 port = r->connection->local_addr->port; 882 883 /* Recall that the name_chain is a list of server_addr_recs, some of 884 * whose ports may not match. Also each server may appear more than 885 * once in the chain -- specifically, it will appear once for each 886 * address from its VirtualHost line which matched. We only want to 887 * do the full ServerName/ServerAlias comparisons once for each 888 * server, fortunately we know that all the VirtualHost addresses for 889 * a single server are adjacent to each other. 890 */ 891 892 for (src = r->connection->vhost_lookup_data; src; src = src->next) { 893 server_addr_rec *sar; 894 895 /* We only consider addresses on the name_chain which have a matching 896 * port 897 */ 898 sar = src->sar; 899 if (sar->host_port != 0 && port != sar->host_port) { 900 continue; 901 } 902 903 s = src->server; 904 905 /* If we still need to do ServerName and ServerAlias checks for this 906 * server, do them now. 907 */ 908 if (s != last_s) { 909 /* does it match any ServerName or ServerAlias directive? */ 910 if (matches_aliases(s, host)) { 911 goto found; 912 } 913 } 914 last_s = s; 915 916 /* Fallback: does it match the virthost from the sar? */ 917 if (!strcasecmp(host, sar->virthost)) { 918 /* only the first match is used */ 919 if (virthost_s == NULL) { 920 virthost_s = s; 921 } 922 } 923 } 924 925 /* If ServerName and ServerAlias check failed, we end up here. If it 926 * matches a VirtualHost, virthost_s is set. Use that as fallback 927 */ 928 if (virthost_s) { 929 s = virthost_s; 930 goto found; 931 } 932 933 return; 934 935found: 936 /* s is the first matching server, we're done */ 937 r->server = s; 938} 939 940 941static void check_serverpath(request_rec *r) 942{ 943 server_rec *s; 944 server_rec *last_s; 945 name_chain *src; 946 apr_port_t port; 947 948 port = r->connection->local_addr->port; 949 950 /* 951 * This is in conjunction with the ServerPath code in http_core, so we 952 * get the right host attached to a non- Host-sending request. 953 * 954 * See the comment in check_hostalias about how each vhost can be 955 * listed multiple times. 956 */ 957 958 last_s = NULL; 959 for (src = r->connection->vhost_lookup_data; src; src = src->next) { 960 /* We only consider addresses on the name_chain which have a matching 961 * port 962 */ 963 if (src->sar->host_port != 0 && port != src->sar->host_port) { 964 continue; 965 } 966 967 s = src->server; 968 if (s == last_s) { 969 continue; 970 } 971 last_s = s; 972 973 if (s->path && !strncmp(r->uri, s->path, s->pathlen) && 974 (s->path[s->pathlen - 1] == '/' || 975 r->uri[s->pathlen] == '/' || 976 r->uri[s->pathlen] == '\0')) { 977 r->server = s; 978 return; 979 } 980 } 981} 982 983 984AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r) 985{ 986 /* must set this for HTTP/1.1 support */ 987 if (r->hostname || (r->hostname = apr_table_get(r->headers_in, "Host"))) { 988 fix_hostname(r); 989 if (r->status != HTTP_OK) 990 return; 991 } 992 /* check if we tucked away a name_chain */ 993 if (r->connection->vhost_lookup_data) { 994 if (r->hostname) 995 check_hostalias(r); 996 else 997 check_serverpath(r); 998 } 999} 1000 1001/** 1002 * For every virtual host on this connection, call func_cb. 1003 */ 1004AP_DECLARE(int) ap_vhost_iterate_given_conn(conn_rec *conn, 1005 ap_vhost_iterate_conn_cb func_cb, 1006 void* baton) 1007{ 1008 server_rec *s; 1009 server_rec *last_s; 1010 name_chain *src; 1011 apr_port_t port; 1012 int rv = 0; 1013 1014 if (conn->vhost_lookup_data) { 1015 last_s = NULL; 1016 port = conn->local_addr->port; 1017 1018 for (src = conn->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 1022 * matching 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 (s == last_s) { 1032 /* we've already done a callback for this vhost. */ 1033 continue; 1034 } 1035 1036 last_s = s; 1037 1038 rv = func_cb(baton, conn, s); 1039 1040 if (rv != 0) { 1041 break; 1042 } 1043 } 1044 } 1045 else { 1046 rv = func_cb(baton, conn, conn->base_server); 1047 } 1048 1049 return rv; 1050} 1051 1052/* Called for a new connection which has a known local_addr. Note that the 1053 * new connection is assumed to have conn->server == main server. 1054 */ 1055AP_DECLARE(void) ap_update_vhost_given_ip(conn_rec *conn) 1056{ 1057 ipaddr_chain *trav; 1058 apr_port_t port; 1059 1060 /* scan the hash table for an exact match first */ 1061 trav = find_ipaddr(conn->local_addr); 1062 1063 if (trav) { 1064 /* save the name_chain for later in case this is a name-vhost */ 1065 conn->vhost_lookup_data = trav->names; 1066 conn->base_server = trav->server; 1067 return; 1068 } 1069 1070 /* maybe there's a default server or wildcard name-based vhost 1071 * matching this port 1072 */ 1073 port = conn->local_addr->port; 1074 1075 trav = find_default_server(port); 1076 if (trav) { 1077 conn->vhost_lookup_data = trav->names; 1078 conn->base_server = trav->server; 1079 return; 1080 } 1081 1082 /* otherwise we're stuck with just the main server 1083 * and no name-based vhosts 1084 */ 1085 conn->vhost_lookup_data = NULL; 1086} 1087