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
This commit is contained in:
Omar Polo 2023-06-24 10:02:46 +00:00
parent 35dd3fc8ce
commit aa30aaedc8
1 changed files with 37 additions and 16 deletions

View File

@ -92,6 +92,17 @@ static uint32_t server_client_id;
struct client_tree_id clients; 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 static inline int
matches(const char *pattern, const char *path) matches(const char *pattern, const char *path)
{ {
@ -100,6 +111,28 @@ matches(const char *pattern, const char *path)
return !fnmatch(pattern, path, 0); 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 * const char *
vhost_lang(struct vhost *v, const char *path) 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 client *c = d;
struct conf *conf = c->conf; struct conf *conf = c->conf;
struct vhost *h; struct vhost *h;
struct alist *a;
const char *servname; const char *servname;
const char *parse_err = "unknown error"; const char *parse_err = "unknown error";
@ -442,16 +474,10 @@ handle_handshake(int fd, short ev, void *d)
goto err; goto err;
} }
TAILQ_FOREACH(h, &conf->hosts, vhosts) { TAILQ_FOREACH(h, &conf->hosts, vhosts)
if (matches(h->domain, c->domain)) if (match_host(h, c))
goto found; break;
TAILQ_FOREACH(a, &h->aliases, aliases) {
if (matches(a->alias, c->domain))
goto found;
}
}
found:
log_debug("handshake: SNI: \"%s\"; decoded: \"%s\"; matched: \"%s\"", log_debug("handshake: SNI: \"%s\"; decoded: \"%s\"; matched: \"%s\"",
servname != NULL ? servname : "(null)", servname != NULL ? servname : "(null)",
c->domain, c->domain,
@ -1374,12 +1400,7 @@ add_matching_kps(struct tls_config *tlsconf, struct address *addr,
TAILQ_FOREACH(h, &conf->hosts, vhosts) { TAILQ_FOREACH(h, &conf->hosts, vhosts) {
TAILQ_FOREACH(vaddr, &h->addrs, addrs) { TAILQ_FOREACH(vaddr, &h->addrs, addrs) {
if (addr->ai_flags != vaddr->ai_flags || if (!match_addr(addr, vaddr))
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)
continue; continue;
if (!any) { if (!any) {