/*
 * QEMU VNC display driver: Websockets support
 *
 * Copyright (C) 2010 Joel Martin
 * Copyright (C) 2012 Tim Hardeck
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this software; if not, see <http://www.gnu.org/licenses/>.
 */

#include "vnc.h"
#include "qemu/main-loop.h"

#ifdef CONFIG_VNC_TLS
#include "qemu/sockets.h"

static int vncws_start_tls_handshake(struct VncState *vs)
{
    int ret = gnutls_handshake(vs->tls.session);

    if (ret < 0) {
        if (!gnutls_error_is_fatal(ret)) {
            VNC_DEBUG("Handshake interrupted (blocking)\n");
            if (!gnutls_record_get_direction(vs->tls.session)) {
                qemu_set_fd_handler(vs->csock, vncws_tls_handshake_io,
                                    NULL, vs);
            } else {
                qemu_set_fd_handler(vs->csock, NULL, vncws_tls_handshake_io,
                                    vs);
            }
            return 0;
        }
        VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
        vnc_client_error(vs);
        return -1;
    }

    if (vs->vd->tls.x509verify) {
        if (vnc_tls_validate_certificate(vs) < 0) {
            VNC_DEBUG("Client verification failed\n");
            vnc_client_error(vs);
            return -1;
        } else {
            VNC_DEBUG("Client verification passed\n");
        }
    }

    VNC_DEBUG("Handshake done, switching to TLS data mode\n");
    qemu_set_fd_handler2(vs->csock, NULL, vncws_handshake_read, NULL, vs);

    return 0;
}

void vncws_tls_handshake_io(void *opaque)
{
    struct VncState *vs = (struct VncState *)opaque;

    if (!vs->tls.session) {
        VNC_DEBUG("TLS Websocket setup\n");
        if (vnc_tls_client_setup(vs, vs->vd->tls.x509cert != NULL) < 0) {
            return;
        }
    }
    VNC_DEBUG("Handshake IO continue\n");
    vncws_start_tls_handshake(vs);
}
#endif /* CONFIG_VNC_TLS */

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);
    }
}


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_write_ws(VncState *vs)
{
    long ret;
    VNC_DEBUG("Write WS: Pending output %p size %zd offset %zd\n",
              vs->output.buffer, vs->output.capacity, vs->output.offset);
    vncws_encode_frame(&vs->ws_output, vs->output.buffer, vs->output.offset);
    buffer_reset(&vs->output);
    ret = vnc_client_write_buf(vs, vs->ws_output.buffer, vs->ws_output.offset);
    if (!ret) {
        return 0;
    }

    buffer_advance(&vs->ws_output, ret);

    if (vs->ws_output.offset == 0) {
        qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
    }

    return ret;
}

static char *vncws_extract_handshake_entry(const char *handshake,
        size_t handshake_len, const char *name)
{
    char *begin, *end, *ret = NULL;
    char *line = g_strdup_printf("%s%s: ", WS_HANDSHAKE_DELIM, name);
    begin = g_strstr_len(handshake, handshake_len, line);
    if (begin != NULL) {
        begin += strlen(line);
        end = g_strstr_len(begin, handshake_len - (begin - handshake),
                WS_HANDSHAKE_DELIM);
        if (end != NULL) {
            ret = g_strndup(begin, end - begin);
        }
    }
    g_free(line);
    return ret;
}

static void vncws_send_handshake_response(VncState *vs, const char* key)
{
    char combined_key[WS_CLIENT_KEY_LEN + WS_GUID_LEN + 1];
    unsigned char hash[SHA1_DIGEST_LEN];
    size_t hash_size = sizeof(hash);
    char *accept = NULL, *response = NULL;
    gnutls_datum_t in;
    int ret;

    g_strlcpy(combined_key, key, WS_CLIENT_KEY_LEN + 1);
    g_strlcat(combined_key, WS_GUID, WS_CLIENT_KEY_LEN + WS_GUID_LEN + 1);

    /* hash and encode it */
    in.data = (void *)combined_key;
    in.size = WS_CLIENT_KEY_LEN + WS_GUID_LEN;
    ret = gnutls_fingerprint(GNUTLS_DIG_SHA1, &in, hash, &hash_size);
    if (ret == GNUTLS_E_SUCCESS && hash_size <= SHA1_DIGEST_LEN) {
        accept = g_base64_encode(hash, hash_size);
    }
    if (accept == NULL) {
        VNC_DEBUG("Hashing Websocket combined key failed\n");
        vnc_client_error(vs);
        return;
    }

    response = g_strdup_printf(WS_HANDSHAKE, accept);
    vnc_client_write_buf(vs, (const uint8_t *)response, strlen(response));

    g_free(accept);
    g_free(response);

    vs->encode_ws = 1;
    vnc_init_state(vs);
}

void vncws_process_handshake(VncState *vs, uint8_t *line, size_t size)
{
    char *protocols = vncws_extract_handshake_entry((const char *)line, size,
            "Sec-WebSocket-Protocol");
    char *version = vncws_extract_handshake_entry((const char *)line, size,
            "Sec-WebSocket-Version");
    char *key = vncws_extract_handshake_entry((const char *)line, size,
            "Sec-WebSocket-Key");

    if (protocols && version && key
            && g_strrstr(protocols, "binary")
            && !strcmp(version, WS_SUPPORTED_VERSION)
            && strlen(key) == WS_CLIENT_KEY_LEN) {
        vncws_send_handshake_response(vs, key);
    } else {
        VNC_DEBUG("Defective Websockets header or unsupported protocol\n");
        vnc_client_error(vs);
    }

    g_free(protocols);
    g_free(version);
    g_free(key);
}

void vncws_encode_frame(Buffer *output, const void *payload,
        const size_t payload_size)
{
    size_t header_size = 0;
    unsigned char opcode = WS_OPCODE_BINARY_FRAME;
    union {
        char buf[WS_HEAD_MAX_LEN];
        WsHeader ws;
    } header;

    if (!payload_size) {
        return;
    }

    header.ws.b0 = 0x80 | (opcode & 0x0f);
    if (payload_size <= 125) {
        header.ws.b1 = (uint8_t)payload_size;
        header_size = 2;
    } else if (payload_size < 65536) {
        header.ws.b1 = 0x7e;
        header.ws.u.s16.l16 = cpu_to_be16((uint16_t)payload_size);
        header_size = 4;
    } else {
        header.ws.b1 = 0x7f;
        header.ws.u.s64.l64 = cpu_to_be64(payload_size);
        header_size = 10;
    }

    buffer_reserve(output, header_size + payload_size);
    buffer_append(output, header.buf, header_size);
    buffer_append(output, payload, payload_size);
}

int vncws_decode_frame_header(Buffer *input,
                              size_t *header_size,
                              size_t *payload_remain,
                              WsMask *payload_mask)
{
    unsigned char opcode = 0, fin = 0, has_mask = 0;
    size_t payload_len;
    WsHeader *header = (WsHeader *)input->buffer;

    if (input->offset < WS_HEAD_MIN_LEN + 4) {
        /* header not complete */
        return 0;
    }

    fin = (header->b0 & 0x80) >> 7;
    opcode = header->b0 & 0x0f;
    has_mask = (header->b1 & 0x80) >> 7;
    payload_len = header->b1 & 0x7f;

    if (opcode == WS_OPCODE_CLOSE) {
        /* disconnect */
        return -1;
    }

    /* Websocket frame sanity check:
     * * Websocket fragmentation is not supported.
     * * All  websockets frames sent by a client have to be masked.
     * * Only binary encoding is supported.
     */
    if (!fin || !has_mask || opcode != WS_OPCODE_BINARY_FRAME) {
        VNC_DEBUG("Received faulty/unsupported Websocket frame\n");
        return -2;
    }

    if (payload_len < 126) {
        *payload_remain = payload_len;
        *header_size = 6;
        *payload_mask = header->u.m;
    } else if (payload_len == 126 && input->offset >= 8) {
        *payload_remain = be16_to_cpu(header->u.s16.l16);
        *header_size = 8;
        *payload_mask = header->u.s16.m16;
    } else if (payload_len == 127 && input->offset >= 14) {
        *payload_remain = be64_to_cpu(header->u.s64.l64);
        *header_size = 14;
        *payload_mask = header->u.s64.m64;
    } else {
        /* header not complete */
        return 0;
    }

    return 1;
}

int vncws_decode_frame_payload(Buffer *input,
                               size_t *payload_remain, WsMask *payload_mask,
                               uint8_t **payload, size_t *payload_size)
{
    size_t i;
    uint32_t *payload32;

    *payload = input->buffer;
    /* If we aren't at the end of the payload, then drop
     * off the last bytes, so we're always multiple of 4
     * for purpose of unmasking, except at end of payload
     */
    if (input->offset < *payload_remain) {
        *payload_size = input->offset - (input->offset % 4);
    } else {
        *payload_size = *payload_remain;
    }
    if (*payload_size == 0) {
        return 0;
    }
    *payload_remain -= *payload_size;

    /* unmask frame */
    /* process 1 frame (32 bit op) */
    payload32 = (uint32_t *)(*payload);
    for (i = 0; i < *payload_size / 4; i++) {
        payload32[i] ^= payload_mask->u;
    }
    /* process the remaining bytes (if any) */
    for (i *= 4; i < *payload_size; i++) {
        (*payload)[i] ^= payload_mask->c[i % 4];
    }

    return 1;
}
