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:
parent
30d992dbe2
commit
3a31c47fcd
4 changed files with 47 additions and 5 deletions
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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],
|
||||
|
|
Loading…
Add table
Reference in a new issue