diff options
author | Omar Polo <op@omarpolo.com> | 2024-05-29 07:52:13 +0000 |
---|---|---|
committer | Omar Polo <op@omarpolo.com> | 2024-05-29 07:52:13 +0000 |
commit | 1ef0cd0cdb6512fad96ecf0830e581af677d5947 (patch) | |
tree | 398ead8e51094c18fda333df8ca9e70b958ebf7a /server.c | |
parent | 42e2af25aec9e9eef05bddc9e408ab2a11e3d5fb (diff) |
relax the SNI requirement
There are legitimate cases where SNI can't be used, for example
when connecting via an IPv6 address, so don't rejects those requests.
Instead, fill the requested domain with the address (literal) of
the socket they're connected to and attempt to match on it.
This possibly still incur in a "won't proxy" error if the client
then requests a different hostname.
See the github issue https://github.com/omar-polo/gmid/issues/25
Diffstat (limited to 'server.c')
-rw-r--r-- | server.c | 26 |
1 files changed, 19 insertions, 7 deletions
@@ -119,6 +119,16 @@ match_host(struct vhost *v, struct client *c) if (addr == NULL) return 0; + if (*c->domain == '\0') { + if (getnameinfo((struct sockaddr *)&addr->ss, addr->slen, + c->domain, sizeof(c->domain), NULL, 0, + NI_NUMERICHOST) == -1) { + log_warn("failed to fill the domain; getnameinfo"); + *c->domain = '\0'; + return 0; + } + } + if (matches(v->domain, c->domain)) return 1; @@ -403,16 +413,19 @@ handle_handshake(int fd, short ev, void *d) evbuffer_unfreeze(c->bev->output, 1); #endif - if ((servname = tls_conn_servername(c->ctx)) == NULL) { + if ((servname = tls_conn_servername(c->ctx)) == NULL) log_debug("handshake: missing SNI"); - goto err; - } - if (!puny_decode(servname, c->domain, sizeof(c->domain), &parse_err)) { log_info("puny_decode: %s", parse_err); - goto err; + start_reply(c, BAD_REQUEST, "Wrong/malformed host"); + return; } + /* + * match_addr will serialize the (matching) address if c->domain + * is empty, so that we can support requests for raw IPv6 address + * that can't have a SNI. + */ TAILQ_FOREACH(h, &conf->hosts, vhosts) if (match_host(h, c)) break; @@ -428,8 +441,7 @@ handle_handshake(int fd, short ev, void *d) return; } -err: - start_reply(c, BAD_REQUEST, "Wrong/malformed host or missing SNI"); + start_reply(c, BAD_REQUEST, "Wrong/malformed host"); } static void |