1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

ws: setting default protocol index to an illegal index disables default ws binding

On lwsws, incoming ws connections to the default vhost
are not rejected by the dummy protocol handler and not
really serviced either, leading to bots connecting to it to
get immortal, idle ws connections with no timeout (since it's an
established ws connection).

Rejecting these connections by default by adding a handler
for ESTABLISHED in the dummy handler will solve it nicely,
but it will break an unknown number of dumb. protocol-less
user implementations that rely on this behaviour by using
break; from their own ESTABLISHED handler and calling
through to the currently NOP dummy handler one.

Add support to assertively disable the default protocol
index used for subprotocol-less ws connections instead.
This commit is contained in:
Andy Green 2019-02-22 14:27:21 +08:00
parent 30d992dbe2
commit 3a31c47fcd
4 changed files with 47 additions and 5 deletions

View file

@ -807,9 +807,18 @@ rops_adoption_bind_h1(struct lws *wsi, int type, const char *vh_prot_name)
lws_role_transition(wsi, LWSIFR_SERVER, (type & LWS_ADOPT_ALLOW_SSL) ?
LRS_SSL_INIT : LRS_HEADERS, &role_ops_h1);
if (!vh_prot_name)
/*
* We have to bind to h1 as a default even when we're actually going to
* replace it as an h2 bind later. So don't take this seriously if the
* default is disabled (ws upgrade caees properly about it)
*/
if (!vh_prot_name && wsi->vhost->default_protocol_index <
wsi->vhost->count_protocols)
wsi->protocol = &wsi->vhost->protocols[
wsi->vhost->default_protocol_index];
wsi->vhost->default_protocol_index];
else
wsi->protocol = &wsi->vhost->protocols[0];
/* the transport is accepted... give him time to negotiate */
lws_set_timeout(wsi, PENDING_TIMEOUT_ESTABLISH_WITH_SERVER,

View file

@ -118,6 +118,8 @@ static const char * const paths_vhosts[] = {
"vhosts[].allow-non-tls",
"vhosts[].redirect-http",
"vhosts[].allow-http-on-https",
"vhosts[].disable-no-protocol-ws-upgrades",
};
enum lejp_vhost_paths {
@ -182,6 +184,8 @@ enum lejp_vhost_paths {
LEJPVP_FLAG_ALLOW_NON_TLS,
LEJPVP_FLAG_REDIRECT_HTTP,
LEJPVP_FLAG_ALLOW_HTTP_ON_HTTPS,
LEJPVP_FLAG_DISABLE_NO_PROTOCOL_WS_UPGRADES,
};
static const char * const parser_errs[] = {
@ -228,6 +232,7 @@ struct jpargs {
const char **plugin_dirs;
int count_plugin_dirs;
unsigned int reject_ws_with_no_protocol:1;
unsigned int enable_client_ssl:1;
unsigned int fresh_mount:1;
unsigned int any_vhosts:1;
@ -367,6 +372,7 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
const char *ss;
/* set the defaults for this vhost */
a->reject_ws_with_no_protocol = 0;
a->valid = 1;
a->head = NULL;
a->last = NULL;
@ -502,6 +508,12 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
}
a->any_vhosts = 1;
if (a->reject_ws_with_no_protocol) {
a->reject_ws_with_no_protocol = 0;
vhost->default_protocol_index = 255;
}
#if defined(LWS_WITH_TLS)
if (a->enable_client_ssl) {
const char *cert_filepath =
@ -835,6 +847,10 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
LWS_SERVER_OPTION_ALLOW_HTTP_ON_HTTPS_LISTENER);
return 0;
case LEJPVP_FLAG_DISABLE_NO_PROTOCOL_WS_UPGRADES:
a->reject_ws_with_no_protocol = 1;
return 0;
default:
return 0;
}

View file

@ -63,9 +63,14 @@ rops_adoption_bind_raw_file(struct lws *wsi, int type, const char *vh_prot_name)
lws_role_transition(wsi, 0, LRS_ESTABLISHED, &role_ops_raw_file);
if (!vh_prot_name)
if (!vh_prot_name) {
if (wsi->vhost->default_protocol_index >=
wsi->vhost->count_protocols)
return 0;
wsi->protocol = &wsi->vhost->protocols[
wsi->vhost->default_protocol_index];
}
return 1; /* bound */
}

View file

@ -323,10 +323,22 @@ lws_process_ws_upgrade(struct lws *wsi)
if (!ts.len) {
int n = wsi->vhost->default_protocol_index;
/*
* some clients only have one protocol and do not send the
* Some clients only have one protocol and do not send the
* protocol list header... allow it and match to the vhost's
* default protocol (which itself defaults to zero)
* default protocol (which itself defaults to zero).
*
* Setting the vhost default protocol index to -1 or anything
* more than the actual number of protocols on the vhost causes
* these "no protocol" ws connections to be rejected.
*/
if (n >= wsi->vhost->count_protocols) {
lwsl_notice("%s: rejecting ws upg with no protocol\n",
__func__);
return 1;
}
lwsl_info("%s: defaulting to prot handler %d\n", __func__, n);
lws_bind_protocol(wsi, &wsi->vhost->protocols[n],