Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

WebSocket : Fix possible crash (ietf-06)

  • Loading branch information...
commit d4207876ffd149c2d13f889f94b592fdcc631a8e 1 parent 9b89b42
@paraboul paraboul authored
View
2  bin/ape.conf
@@ -6,7 +6,7 @@ uid {
Server {
- port = 6969
+ port = 443
daemon = no
ip_listen = 0.0.0.0
domain = auto
View
36 src/http.c
@@ -113,18 +113,13 @@ static void process_websocket_frame(ape_socket *co, acetables *g_ape)
websocket_state *websocket = co->parser.data;
ape_parser *parser = &co->parser;
- char *data = &buffer->data[websocket->offset];
-
if (websocket->step == WS_STEP_KEY) {
int toread = MIN(4 - websocket->offset, buffer->length - websocket->offset);
- memcpy(websocket->key.val+websocket->offset, data, toread);
+ memcpy(websocket->key.val+websocket->offset, &buffer->data[websocket->offset], toread);
websocket->offset += toread;
if (websocket->offset == 4) {
- websocket->offset = 0;
-
- data = &buffer->data[4];
websocket->step = WS_STEP_START;
} else {
@@ -132,19 +127,19 @@ static void process_websocket_frame(ape_socket *co, acetables *g_ape)
}
}
- while(&data[websocket->offset] != &buffer->data[buffer->length]) {
+ while(&buffer->data[websocket->offset] != &buffer->data[buffer->length]) {
/* de-cypher the payload with the 32bit key */
- data[websocket->offset] ^= websocket->key.val[websocket->key.pos++ % 4];
-
+ buffer->data[websocket->offset] ^= websocket->key.val[websocket->key.pos++ % 4];
+
if (websocket->step != WS_STEP_DATA) {
- memcpy(((char *)&websocket->frame_payload)+websocket->offset,
- &data[websocket->offset], 1);
+ memcpy(((char *)&websocket->frame_payload)+(websocket->offset-4),
+ &buffer->data[websocket->offset], 1);
switch(websocket->offset) {
- case 0:
+ case 0+4:
websocket->step = WS_STEP_LENGTH;
break;
- case 1:
+ case 1+4:
/* Remove the RSV4 bit */
websocket->frame_payload.length &= 0x7F;
@@ -157,21 +152,24 @@ static void process_websocket_frame(ape_socket *co, acetables *g_ape)
websocket->step = WS_STEP_DATA;
}
break;
- case 3:
+ case 3+4:
if (websocket->step == WS_STEP_SHORT_LENGTH) {
websocket->frame_payload.extended_length = ntohs(websocket->frame_payload.short_length);
websocket->step = WS_STEP_DATA;
}
break;
- case 9:
+ case 9+4:
websocket->step = WS_STEP_DATA;
- /* TODO : 64bit Network bit order to host bit order */
+ websocket->frame_payload.extended_length = ntohl(websocket->frame_payload.extended_length >> 32);
break;
}
} else if (websocket->frame_payload.extended_length != 0) {
- if (websocket->data == NULL) {
- websocket->data = &data[websocket->offset];
+ if (websocket->data == NULL || websocket->data != &buffer->data[websocket->data_pos]) {
+ if (websocket->data_pos == 0) {
+ websocket->data_pos = websocket->offset;
+ }
+ websocket->data = &buffer->data[websocket->data_pos];
}
if (--websocket->frame_payload.extended_length == 0) {
@@ -191,7 +189,7 @@ static void process_websocket_frame(ape_socket *co, acetables *g_ape)
break;
default:
/* Data frame */
- data[websocket->offset+1] = '\0';
+ buffer->data[websocket->offset+1] = '\0';
parser->onready(parser, g_ape);
break;
}
View
3  src/main.h
@@ -124,7 +124,7 @@ typedef struct _websocket_state
{
struct _http_state *http;
const char *data;
- unsigned short int offset;
+ unsigned int offset;
unsigned short int error;
ws_version version;
@@ -146,6 +146,7 @@ typedef struct _websocket_state
} frame_payload;
#pragma pack()
ws_payload_step step;
+ int data_pos;
} websocket_state;
typedef enum {
View
1  src/parser.c
@@ -114,6 +114,7 @@ ape_parser parser_init_stream(ape_socket *co)
websocket->frame_payload.start = 0;
websocket->frame_payload.length = 0;
websocket->frame_payload.extended_length = 0;
+ websocket->data_pos = 0;
websocket->step = WS_STEP_KEY;
View
5 src/raw.c
@@ -392,7 +392,7 @@ int send_raws(subuser *user, acetables *g_ape)
if (user->user->transport == TRANSPORT_WEBSOCKET_IETF) {
char payload_head[32] = { 0x84 };
- int payload_size = raws_size(user);
+ int payload_size = raws_size(user); /* TODO: fragmentation? */
int payload_length = 0;
if (payload_size <= 125) {
@@ -413,11 +413,10 @@ int send_raws(subuser *user, acetables *g_ape)
payload_head[3] = 0;
payload_head[4] = 0;
payload_head[5] = 0;
-
+
memcpy(&payload_head[6], &s, 4);
payload_length = 10;
- /* TODO: handle large payload */
}
finish &= sendbin(user->client->fd, payload_head, payload_length, 0, g_ape);
Please sign in to comment.
Something went wrong with that request. Please try again.