commit aa30aaedc819776e80078811ba0fd896c7216405 from: Omar Polo date: Sat Jun 24 10:02:46 2023 UTC don't match host if connecting from the wrong socket limit how one given virtual host can be reached based on its `listen on' lists commit - 35dd3fc8ce5c195b5b56d1711798da718cbb50e7 commit + aa30aaedc819776e80078811ba0fd896c7216405 blob - 80043e9473ff3be59346aa70e11e3cb8696c1f8c blob + 076dae860eacaf7a2ab9e0f1f0523d5b69afd9a0 --- server.c +++ server.c @@ -93,6 +93,17 @@ static uint32_t server_client_id; struct client_tree_id clients; static inline int +match_addr(struct address *target, struct address *source) +{ + return (target->ai_flags == source->ai_flags && + target->ai_family == source->ai_family && + target->ai_socktype == source->ai_socktype && + target->ai_protocol == source->ai_protocol && + target->slen == source->slen && + !memcmp(&target->ss, &source->ss, target->slen)); +} + +static inline int matches(const char *pattern, const char *path) { if (*path == '/') @@ -100,6 +111,28 @@ matches(const char *pattern, const char *path) return !fnmatch(pattern, path, 0); } +static inline int +match_host(struct vhost *v, struct client *c) +{ + struct alist *a; + struct address *addr; + + TAILQ_FOREACH(addr, &v->addrs, addrs) + if (match_addr(addr, c->addr)) + break; + if (addr == NULL) + return 0; + + if (matches(v->domain, c->domain)) + return 1; + + TAILQ_FOREACH(a, &v->aliases, aliases) + if (matches(a->alias, c->domain)) + return 1; + + return 0; +} + const char * vhost_lang(struct vhost *v, const char *path) { @@ -398,7 +431,6 @@ handle_handshake(int fd, short ev, void *d) struct client *c = d; struct conf *conf = c->conf; struct vhost *h; - struct alist *a; const char *servname; const char *parse_err = "unknown error"; @@ -442,16 +474,10 @@ handle_handshake(int fd, short ev, void *d) goto err; } - TAILQ_FOREACH(h, &conf->hosts, vhosts) { - if (matches(h->domain, c->domain)) - goto found; - TAILQ_FOREACH(a, &h->aliases, aliases) { - if (matches(a->alias, c->domain)) - goto found; - } - } + TAILQ_FOREACH(h, &conf->hosts, vhosts) + if (match_host(h, c)) + break; -found: log_debug("handshake: SNI: \"%s\"; decoded: \"%s\"; matched: \"%s\"", servname != NULL ? servname : "(null)", c->domain, @@ -1374,12 +1400,7 @@ add_matching_kps(struct tls_config *tlsconf, struct ad TAILQ_FOREACH(h, &conf->hosts, vhosts) { TAILQ_FOREACH(vaddr, &h->addrs, addrs) { - if (addr->ai_flags != vaddr->ai_flags || - addr->ai_family != vaddr->ai_family || - addr->ai_socktype != vaddr->ai_socktype || - addr->ai_protocol != vaddr->ai_protocol || - addr->slen != vaddr->slen || - memcmp(&addr->ss, &vaddr->ss, addr->slen) != 0) + if (!match_addr(addr, vaddr)) continue; if (!any) {