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

Added optional per-header length limits:

- libwebsockets.h:
 - * added struct lws_token_limits
   * added token limits pointer to lws_context_creation_info
 - private-libwebsockets.h: added token limits pointer to lws_context_creation_info
 - context.c: copy token limits in create_context
 - client.c / server.c: pass context when invoking libwebsocket_parse
 - parsers.c:
 - * libwebsocket_parse takes context pointer
   * issue_char takes context pointer and checks header length against context limits, if defined
   * issue_char returns 1 (not -1/0) for header too long, and spill: sets the state to WSI_TOKEN_SKIPPING
This commit is contained in:
Andrew Canaday 2014-06-29 00:25:19 -04:00 committed by Andy Green
parent b57e7a0e2e
commit 74b4a65745
6 changed files with 39 additions and 12 deletions

View file

@ -411,7 +411,7 @@ int lws_client_socket_service(struct libwebsocket_context *context,
return 0;
}
if (libwebsocket_parse(wsi, c)) {
if (libwebsocket_parse(context, wsi, c)) {
lwsl_warn("problems parsing header\n");
goto bail3;
}

View file

@ -116,6 +116,7 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
context->listen_service_extraseen = 0;
context->protocols = info->protocols;
context->token_limits = info->token_limits;
context->listen_port = info->port;
context->http_proxy_port = 0;
context->http_proxy_address[0] = '\0';

View file

@ -341,6 +341,10 @@ enum lws_token_indexes {
WSI_INIT_TOKEN_MUXURL,
};
struct lws_token_limits {
unsigned short token_limit[WSI_TOKEN_COUNT];
};
/*
* From RFC 6455
1000
@ -947,6 +951,7 @@ struct lws_context_creation_info {
const char *iface;
struct libwebsocket_protocols *protocols;
struct libwebsocket_extension *extensions;
struct lws_token_limits *token_limits;
const char *ssl_cert_filepath;
const char *ssl_private_key_filepath;
const char *ssl_ca_filepath;

View file

@ -165,12 +165,22 @@ static char char_to_hex(const char c)
return -1;
}
static int issue_char(struct libwebsocket *wsi, unsigned char c)
static int issue_char(
struct libwebsocket_context *context,
struct libwebsocket *wsi, unsigned char c)
{
if (wsi->u.hdr.ah->pos == sizeof(wsi->u.hdr.ah->data)) {
lwsl_warn("excessive header content\n");
return -1;
}
if( context->token_limits &&
(wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len >=
context->token_limits->token_limit[wsi->u.hdr.parser_state]) ) {
lwsl_warn("header %i exceeds limit\n", wsi->u.hdr.parser_state);
return 1;
};
wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = c;
if (c)
wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len++;
@ -178,7 +188,9 @@ static int issue_char(struct libwebsocket *wsi, unsigned char c)
return 0;
}
int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
int libwebsocket_parse(
struct libwebsocket_context *context,
struct libwebsocket *wsi, unsigned char c)
{
int n;
@ -234,7 +246,7 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
if (c == ' ') {
/* enforce starting with / */
if (!wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len)
if (issue_char(wsi, '/') < 0)
if (issue_char(context, wsi, '/') < 0)
return -1;
c = '\0';
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
@ -253,7 +265,7 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
case URIES_SEEN_PERCENT:
if (char_to_hex(c) < 0) {
/* regurgitate */
if (issue_char(wsi, '%') < 0)
if (issue_char(context, wsi, '%') < 0)
return -1;
wsi->u.hdr.ues = URIES_IDLE;
/* continue on to assess c */
@ -266,10 +278,10 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
case URIES_SEEN_PERCENT_H1:
if (char_to_hex(c) < 0) {
/* regurgitate */
issue_char(wsi, '%');
issue_char(context, wsi, '%');
wsi->u.hdr.ues = URIES_IDLE;
/* regurgitate + assess */
if (libwebsocket_parse(wsi, wsi->u.hdr.esc_stash) < 0)
if (libwebsocket_parse(context, wsi, wsi->u.hdr.esc_stash) < 0)
return -1;
/* continue on to assess c */
break;
@ -332,7 +344,7 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
}
/* it was like /.dir ... regurgitate the . */
wsi->u.hdr.ups = URIPS_IDLE;
issue_char(wsi, '.');
issue_char(context, wsi, '.');
break;
case URIPS_SEEN_SLASH_DOT_DOT:
@ -383,8 +395,15 @@ check_eol:
}
spill:
if (issue_char(wsi, c) < 0)
return -1;
{
int issue_result = issue_char(context, wsi, c);
if (issue_result < 0) {
return -1;
}
else if(issue_result > 0) {
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
};
};
swallow:
/* per-protocol end of headers management */

View file

@ -432,6 +432,7 @@ struct libwebsocket_context {
#ifndef LWS_NO_EXTENSIONS
struct libwebsocket_extension *extensions;
#endif
struct lws_token_limits *token_limits;
void *user_space;
};
@ -645,7 +646,8 @@ LWS_EXTERN int
libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c);
LWS_EXTERN int
libwebsocket_parse(struct libwebsocket *wsi, unsigned char c);
libwebsocket_parse(struct libwebsocket_context *context,
struct libwebsocket *wsi, unsigned char c);
LWS_EXTERN int
lws_b64_selftest(void);

View file

@ -179,7 +179,7 @@ int lws_handshake_server(struct libwebsocket_context *context,
/* LWS_CONNMODE_WS_SERVING */
while (len--) {
if (libwebsocket_parse(wsi, *(*buf)++)) {
if (libwebsocket_parse(context, wsi, *(*buf)++)) {
lwsl_info("libwebsocket_parse failed\n");
goto bail_nuke_ah;
}