void vncws_handshake_read(void *opaque) { VncState *vs = opaque; uint8_t *handshake_end; long ret; /* Typical HTTP headers from novnc are 512 bytes, so limiting * total header size to 4096 is easily enough. */ size_t want = 4096 - vs->ws_input.offset; buffer_reserve(&vs->ws_input, want); ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), want); if (!ret) { if (vs->csock == -1) { vnc_disconnect_finish(vs); } return; } vs->ws_input.offset += ret; handshake_end = (uint8_t *)g_strstr_len((char *)vs->ws_input.buffer, vs->ws_input.offset, WS_HANDSHAKE_END); if (handshake_end) { qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs); vncws_process_handshake(vs, vs->ws_input.buffer, vs->ws_input.offset); buffer_advance(&vs->ws_input, handshake_end - vs->ws_input.buffer + strlen(WS_HANDSHAKE_END)); } else if (vs->ws_input.offset >= 4096) { VNC_DEBUG("End of headers not found in first 4096 bytes\n"); vnc_client_error(vs); } }
void vncws_handshake_read(void *opaque) { VncState *vs = opaque; uint8_t *handshake_end; long ret; buffer_reserve(&vs->ws_input, 4096); ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), 4096); if (!ret) { if (vs->csock == -1) { vnc_disconnect_finish(vs); } return; } vs->ws_input.offset += ret; handshake_end = (uint8_t *)g_strstr_len((char *)vs->ws_input.buffer, vs->ws_input.offset, WS_HANDSHAKE_END); if (handshake_end) { qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs); vncws_process_handshake(vs, vs->ws_input.buffer, vs->ws_input.offset); buffer_advance(&vs->ws_input, handshake_end - vs->ws_input.buffer + strlen(WS_HANDSHAKE_END)); } }
long vnc_client_read_ws(VncState *vs) { int ret, err; uint8_t *payload; size_t payload_size, frame_size; VNC_DEBUG("Read websocket %p size %zd offset %zd\n", vs->ws_input.buffer, vs->ws_input.capacity, vs->ws_input.offset); buffer_reserve(&vs->ws_input, 4096); ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), 4096); if (!ret) { return 0; } vs->ws_input.offset += ret; /* make sure that nothing is left in the ws_input buffer */ do { err = vncws_decode_frame(&vs->ws_input, &payload, &payload_size, &frame_size); if (err <= 0) { return err; } buffer_reserve(&vs->input, payload_size); buffer_append(&vs->input, payload, payload_size); buffer_advance(&vs->ws_input, frame_size); } while (vs->ws_input.offset > 0); return ret; }
long vnc_client_read_ws(VncState *vs) { int ret, err; uint8_t *payload; size_t payload_size, header_size; VNC_DEBUG("Read websocket %p size %zd offset %zd\n", vs->ws_input.buffer, vs->ws_input.capacity, vs->ws_input.offset); buffer_reserve(&vs->ws_input, 4096); ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), 4096); if (!ret) { return 0; } vs->ws_input.offset += ret; ret = 0; /* consume as much of ws_input buffer as possible */ do { if (vs->ws_payload_remain == 0) { err = vncws_decode_frame_header(&vs->ws_input, &header_size, &vs->ws_payload_remain, &vs->ws_payload_mask); if (err <= 0) { return err; } buffer_advance(&vs->ws_input, header_size); } if (vs->ws_payload_remain != 0) { err = vncws_decode_frame_payload(&vs->ws_input, &vs->ws_payload_remain, &vs->ws_payload_mask, &payload, &payload_size); if (err < 0) { return err; } if (err == 0) { return ret; } ret += err; buffer_reserve(&vs->input, payload_size); buffer_append(&vs->input, payload, payload_size); buffer_advance(&vs->ws_input, payload_size); } } while (vs->ws_input.offset > 0); return ret; }
long vnc_client_read_sasl(VncState *vs) { long ret; uint8_t encoded[4096]; const char *decoded; unsigned int decodedLen; int err; ret = vnc_client_read_buf(vs, encoded, sizeof(encoded)); if (!ret) return 0; err = sasl_decode(vs->sasl.conn, (char *)encoded, ret, &decoded, &decodedLen); if (err != SASL_OK) return vnc_client_io_error(vs, -1, NULL); VNC_DEBUG("Read SASL Encoded %p size %ld Decoded %p size %d\n", encoded, ret, decoded, decodedLen); buffer_reserve(&vs->input, decodedLen); buffer_append(&vs->input, decoded, decodedLen); return decodedLen; }