From aa30aaedc819776e80078811ba0fd896c7216405 Mon Sep 17 00:00:00 2001 From: Omar Polo Date: Sat, 24 Jun 2023 10:02:46 +0000 Subject: [PATCH] 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 --- server.c | 53 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/server.c b/server.c index 80043e9..076dae8 100644 --- a/server.c +++ b/server.c @@ -92,6 +92,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) { @@ -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 address *addr, 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) {