From 1ef0cd0cdb6512fad96ecf0830e581af677d5947 Mon Sep 17 00:00:00 2001 From: Omar Polo Date: Wed, 29 May 2024 07:52:13 +0000 Subject: [PATCH] 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 --- server.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/server.c b/server.c index b215dad..b9bb0d8 100644 --- a/server.c +++ b/server.c @@ -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