SNI-vhost-matching-fallback-to-wildcard

This commit is contained in:
Andy Green 2016-07-11 09:56:56 +08:00
parent 7d45a746d6
commit f0789545e7
2 changed files with 54 additions and 2 deletions

View file

@ -497,6 +497,25 @@ There are some new members but mainly it's stuff you used to set at
context creation time.
How lws matches hostname or SNI to a vhost
------------------------------------------
LWS first strips any trailing :port number.
Then it tries to find an exact name match for a vhost listening on the correct
port, ie, if SNI or the Host: header provided abc.com:1234, it will match on a
vhost named abc.com that is listening on port 1234.
If there is no exact match, lws will consider wildcard matches, for example
if cats.abc.com:1234 is provided by the client by SNI or Host: header, it will
accept a vhost "abc.com" listening on port 1234. If there was a better, exact,
match, it will have been chosen in preference to this.
Connections with SSL will still have the client go on to check the
certificate allows wildcards and error out if not.
Using lws v2 mounts on a vhost
------------------------------

View file

@ -179,16 +179,48 @@ struct lws_vhost *
lws_select_vhost(struct lws_context *context, int port, const char *servername)
{
struct lws_vhost *vhost = context->vhost_list;
const char *p;
int n, m, colon;
n = strlen(servername);
colon = n;
p = strchr(servername, ':');
if (p)
colon = p - servername;
/* first try exact matches */
while (vhost) {
if (port == vhost->listen_port &&
!strcmp(vhost->name, servername)) {
!strncmp(vhost->name, servername, colon)) {
lwsl_info("SNI: Found: %s\n", servername);
return vhost;
}
vhost = vhost->vhost_next;
}
/*
* if no exact matches, try matching *.vhost-name
* unintentional matches are possible but resolve to x.com for *.x.com
* which is reasonable. If exact match exists we already chose it and
* never reach here. SSL will still fail it if the cert doesn't allow
* *.x.com.
*/
vhost = context->vhost_list;
while (vhost) {
m = strlen(vhost->name);
if (port == vhost->listen_port &&
m <= (colon - 2) &&
servername[colon - m - 1] == '.' &&
!strncmp(vhost->name, servername + colon - m, m)) {
lwsl_info("SNI: Found %s on wildcard: %s\n",
servername, vhost->name);
return vhost;
}
vhost = vhost->vhost_next;
}
return NULL;
}
@ -807,7 +839,8 @@ lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len)
if (vhost)
wsi->vhost = vhost;
}
} else
lwsl_info("no host\n");
wsi->vhost->trans++;
if (!wsi->conn_stat_done) {