xref: /openbmc/qemu/io/channel-websock.c (revision ff1300e626949fa9850b0f91dc5e8c2cb45b6a88)
1 /*
2  * QEMU I/O channels driver websockets
3  *
4  * Copyright (c) 2015 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #include "qemu/osdep.h"
22 #include "qapi/error.h"
23 #include "qemu/bswap.h"
24 #include "io/channel-websock.h"
25 #include "crypto/hash.h"
26 #include "trace.h"
27 
28 #include <time.h>
29 
30 
31 /* Max amount to allow in rawinput/rawoutput buffers */
32 #define QIO_CHANNEL_WEBSOCK_MAX_BUFFER 8192
33 
34 #define QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN 24
35 #define QIO_CHANNEL_WEBSOCK_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
36 #define QIO_CHANNEL_WEBSOCK_GUID_LEN strlen(QIO_CHANNEL_WEBSOCK_GUID)
37 
38 #define QIO_CHANNEL_WEBSOCK_HEADER_PROTOCOL "sec-websocket-protocol"
39 #define QIO_CHANNEL_WEBSOCK_HEADER_VERSION "sec-websocket-version"
40 #define QIO_CHANNEL_WEBSOCK_HEADER_KEY "sec-websocket-key"
41 #define QIO_CHANNEL_WEBSOCK_HEADER_UPGRADE "upgrade"
42 #define QIO_CHANNEL_WEBSOCK_HEADER_HOST "host"
43 #define QIO_CHANNEL_WEBSOCK_HEADER_CONNECTION "connection"
44 
45 #define QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY "binary"
46 #define QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE "Upgrade"
47 #define QIO_CHANNEL_WEBSOCK_UPGRADE_WEBSOCKET "websocket"
48 
49 #define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON \
50     "Server: QEMU VNC\r\n"                       \
51     "Date: %s\r\n"
52 
53 #define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_OK    \
54     "HTTP/1.1 101 Switching Protocols\r\n"      \
55     QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON    \
56     "Upgrade: websocket\r\n"                    \
57     "Connection: Upgrade\r\n"                   \
58     "Sec-WebSocket-Accept: %s\r\n"              \
59     "Sec-WebSocket-Protocol: binary\r\n"        \
60     "\r\n"
61 #define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_NOT_FOUND \
62     "HTTP/1.1 404 Not Found\r\n"                    \
63     QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON        \
64     "Connection: close\r\n"                         \
65     "\r\n"
66 #define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_BAD_REQUEST \
67     "HTTP/1.1 400 Bad Request\r\n"                    \
68     QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON          \
69     "Connection: close\r\n"                           \
70     "Sec-WebSocket-Version: "                         \
71     QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION             \
72     "\r\n"
73 #define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_SERVER_ERR \
74     "HTTP/1.1 500 Internal Server Error\r\n"         \
75     QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON         \
76     "Connection: close\r\n"                          \
77     "\r\n"
78 #define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_TOO_LARGE  \
79     "HTTP/1.1 403 Request Entity Too Large\r\n"      \
80     QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON         \
81     "Connection: close\r\n"                          \
82     "\r\n"
83 #define QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM "\r\n"
84 #define QIO_CHANNEL_WEBSOCK_HANDSHAKE_END "\r\n\r\n"
85 #define QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION "13"
86 #define QIO_CHANNEL_WEBSOCK_HTTP_METHOD "GET"
87 #define QIO_CHANNEL_WEBSOCK_HTTP_PATH "/"
88 #define QIO_CHANNEL_WEBSOCK_HTTP_VERSION "HTTP/1.1"
89 
90 /* The websockets packet header is variable length
91  * depending on the size of the payload... */
92 
93 /* ...length when using 7-bit payload length */
94 #define QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT 6
95 /* ...length when using 16-bit payload length */
96 #define QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT 8
97 /* ...length when using 64-bit payload length */
98 #define QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT 14
99 
100 /* Length of the optional data mask field in header */
101 #define QIO_CHANNEL_WEBSOCK_HEADER_LEN_MASK 4
102 
103 /* Maximum length that can fit in 7-bit payload size */
104 #define QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_7_BIT 126
105 /* Maximum length that can fit in 16-bit payload size */
106 #define QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_16_BIT 65536
107 
108 /* Magic 7-bit length to indicate use of 16-bit payload length */
109 #define QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT 126
110 /* Magic 7-bit length to indicate use of 64-bit payload length */
111 #define QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_64_BIT 127
112 
113 /* Bitmasks for accessing header fields */
114 #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN 0x80
115 #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE 0x0f
116 #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK 0x80
117 #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN 0x7f
118 
119 typedef struct QIOChannelWebsockHeader QIOChannelWebsockHeader;
120 
121 struct QEMU_PACKED QIOChannelWebsockHeader {
122     unsigned char b0;
123     unsigned char b1;
124     union {
125         struct QEMU_PACKED {
126             uint16_t l16;
127             QIOChannelWebsockMask m16;
128         } s16;
129         struct QEMU_PACKED {
130             uint64_t l64;
131             QIOChannelWebsockMask m64;
132         } s64;
133         QIOChannelWebsockMask m;
134     } u;
135 };
136 
137 typedef struct QIOChannelWebsockHTTPHeader QIOChannelWebsockHTTPHeader;
138 
139 struct QIOChannelWebsockHTTPHeader {
140     char *name;
141     char *value;
142 };
143 
144 enum {
145     QIO_CHANNEL_WEBSOCK_OPCODE_CONTINUATION = 0x0,
146     QIO_CHANNEL_WEBSOCK_OPCODE_TEXT_FRAME = 0x1,
147     QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME = 0x2,
148     QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE = 0x8,
149     QIO_CHANNEL_WEBSOCK_OPCODE_PING = 0x9,
150     QIO_CHANNEL_WEBSOCK_OPCODE_PONG = 0xA
151 };
152 
153 static void qio_channel_websock_handshake_send_res(QIOChannelWebsock *ioc,
154                                                    const char *resmsg,
155                                                    ...)
156 {
157     va_list vargs;
158     char *response;
159     size_t responselen;
160 
161     va_start(vargs, resmsg);
162     response = g_strdup_vprintf(resmsg, vargs);
163     responselen = strlen(response);
164     buffer_reserve(&ioc->encoutput, responselen);
165     buffer_append(&ioc->encoutput, response, responselen);
166     va_end(vargs);
167 }
168 
169 static gchar *qio_channel_websock_date_str(void)
170 {
171     struct tm tm;
172     time_t now = time(NULL);
173     char datebuf[128];
174 
175     gmtime_r(&now, &tm);
176 
177     strftime(datebuf, sizeof(datebuf), "%a, %d %b %Y %H:%M:%S GMT", &tm);
178 
179     return g_strdup(datebuf);
180 }
181 
182 static void qio_channel_websock_handshake_send_res_err(QIOChannelWebsock *ioc,
183                                                        const char *resdata)
184 {
185     char *date = qio_channel_websock_date_str();
186     qio_channel_websock_handshake_send_res(ioc, resdata, date);
187     g_free(date);
188 }
189 
190 static size_t
191 qio_channel_websock_extract_headers(QIOChannelWebsock *ioc,
192                                     char *buffer,
193                                     QIOChannelWebsockHTTPHeader *hdrs,
194                                     size_t nhdrsalloc,
195                                     Error **errp)
196 {
197     char *nl, *sep, *tmp;
198     size_t nhdrs = 0;
199 
200     /*
201      * First parse the HTTP protocol greeting of format:
202      *
203      *   $METHOD $PATH $VERSION
204      *
205      * e.g.
206      *
207      *   GET / HTTP/1.1
208      */
209 
210     nl = strstr(buffer, QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM);
211     if (!nl) {
212         error_setg(errp, "Missing HTTP header delimiter");
213         goto bad_request;
214     }
215     *nl = '\0';
216 
217     tmp = strchr(buffer, ' ');
218     if (!tmp) {
219         error_setg(errp, "Missing HTTP path delimiter");
220         return 0;
221     }
222     *tmp = '\0';
223 
224     if (!g_str_equal(buffer, QIO_CHANNEL_WEBSOCK_HTTP_METHOD)) {
225         error_setg(errp, "Unsupported HTTP method %s", buffer);
226         goto bad_request;
227     }
228 
229     buffer = tmp + 1;
230     tmp = strchr(buffer, ' ');
231     if (!tmp) {
232         error_setg(errp, "Missing HTTP version delimiter");
233         goto bad_request;
234     }
235     *tmp = '\0';
236 
237     if (!g_str_equal(buffer, QIO_CHANNEL_WEBSOCK_HTTP_PATH)) {
238         qio_channel_websock_handshake_send_res_err(
239             ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_NOT_FOUND);
240         error_setg(errp, "Unexpected HTTP path %s", buffer);
241         return 0;
242     }
243 
244     buffer = tmp + 1;
245 
246     if (!g_str_equal(buffer, QIO_CHANNEL_WEBSOCK_HTTP_VERSION)) {
247         error_setg(errp, "Unsupported HTTP version %s", buffer);
248         goto bad_request;
249     }
250 
251     buffer = nl + strlen(QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM);
252 
253     /*
254      * Now parse all the header fields of format
255      *
256      *   $NAME: $VALUE
257      *
258      * e.g.
259      *
260      *   Cache-control: no-cache
261      */
262     do {
263         QIOChannelWebsockHTTPHeader *hdr;
264 
265         nl = strstr(buffer, QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM);
266         if (nl) {
267             *nl = '\0';
268         }
269 
270         sep = strchr(buffer, ':');
271         if (!sep) {
272             error_setg(errp, "Malformed HTTP header");
273             goto bad_request;
274         }
275         *sep = '\0';
276         sep++;
277         while (*sep == ' ') {
278             sep++;
279         }
280 
281         if (nhdrs >= nhdrsalloc) {
282             error_setg(errp, "Too many HTTP headers");
283             goto bad_request;
284         }
285 
286         hdr = &hdrs[nhdrs++];
287         hdr->name = buffer;
288         hdr->value = sep;
289 
290         /* Canonicalize header name for easier identification later */
291         for (tmp = hdr->name; *tmp; tmp++) {
292             *tmp = g_ascii_tolower(*tmp);
293         }
294 
295         if (nl) {
296             buffer = nl + strlen(QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM);
297         }
298     } while (nl != NULL);
299 
300     return nhdrs;
301 
302  bad_request:
303     qio_channel_websock_handshake_send_res_err(
304         ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_BAD_REQUEST);
305     return 0;
306 }
307 
308 static const char *
309 qio_channel_websock_find_header(QIOChannelWebsockHTTPHeader *hdrs,
310                                 size_t nhdrs,
311                                 const char *name)
312 {
313     size_t i;
314 
315     for (i = 0; i < nhdrs; i++) {
316         if (g_str_equal(hdrs[i].name, name)) {
317             return hdrs[i].value;
318         }
319     }
320 
321     return NULL;
322 }
323 
324 
325 static void qio_channel_websock_handshake_send_res_ok(QIOChannelWebsock *ioc,
326                                                       const char *key,
327                                                       Error **errp)
328 {
329     char combined_key[QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN +
330                       QIO_CHANNEL_WEBSOCK_GUID_LEN + 1];
331     char *accept = NULL;
332     char *date = qio_channel_websock_date_str();
333 
334     g_strlcpy(combined_key, key, QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN + 1);
335     g_strlcat(combined_key, QIO_CHANNEL_WEBSOCK_GUID,
336               QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN +
337               QIO_CHANNEL_WEBSOCK_GUID_LEN + 1);
338 
339     /* hash and encode it */
340     if (qcrypto_hash_base64(QCRYPTO_HASH_ALG_SHA1,
341                             combined_key,
342                             QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN +
343                             QIO_CHANNEL_WEBSOCK_GUID_LEN,
344                             &accept,
345                             errp) < 0) {
346         qio_channel_websock_handshake_send_res_err(
347             ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_SERVER_ERR);
348         return;
349     }
350 
351     qio_channel_websock_handshake_send_res(
352         ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_OK, date, accept);
353 
354     g_free(date);
355     g_free(accept);
356 }
357 
358 static void qio_channel_websock_handshake_process(QIOChannelWebsock *ioc,
359                                                   char *buffer,
360                                                   Error **errp)
361 {
362     QIOChannelWebsockHTTPHeader hdrs[32];
363     size_t nhdrs = G_N_ELEMENTS(hdrs);
364     const char *protocols = NULL, *version = NULL, *key = NULL,
365         *host = NULL, *connection = NULL, *upgrade = NULL;
366 
367     nhdrs = qio_channel_websock_extract_headers(ioc, buffer, hdrs, nhdrs, errp);
368     if (!nhdrs) {
369         return;
370     }
371 
372     protocols = qio_channel_websock_find_header(
373         hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_PROTOCOL);
374     if (!protocols) {
375         error_setg(errp, "Missing websocket protocol header data");
376         goto bad_request;
377     }
378 
379     version = qio_channel_websock_find_header(
380         hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_VERSION);
381     if (!version) {
382         error_setg(errp, "Missing websocket version header data");
383         goto bad_request;
384     }
385 
386     key = qio_channel_websock_find_header(
387         hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_KEY);
388     if (!key) {
389         error_setg(errp, "Missing websocket key header data");
390         goto bad_request;
391     }
392 
393     host = qio_channel_websock_find_header(
394         hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_HOST);
395     if (!host) {
396         error_setg(errp, "Missing websocket host header data");
397         goto bad_request;
398     }
399 
400     connection = qio_channel_websock_find_header(
401         hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_CONNECTION);
402     if (!connection) {
403         error_setg(errp, "Missing websocket connection header data");
404         goto bad_request;
405     }
406 
407     upgrade = qio_channel_websock_find_header(
408         hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_UPGRADE);
409     if (!upgrade) {
410         error_setg(errp, "Missing websocket upgrade header data");
411         goto bad_request;
412     }
413 
414     if (!g_strrstr(protocols, QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY)) {
415         error_setg(errp, "No '%s' protocol is supported by client '%s'",
416                    QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY, protocols);
417         goto bad_request;
418     }
419 
420     if (!g_str_equal(version, QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION)) {
421         error_setg(errp, "Version '%s' is not supported by client '%s'",
422                    QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION, version);
423         goto bad_request;
424     }
425 
426     if (strlen(key) != QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN) {
427         error_setg(errp, "Key length '%zu' was not as expected '%d'",
428                    strlen(key), QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN);
429         goto bad_request;
430     }
431 
432     if (strcasecmp(connection, QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE) != 0) {
433         error_setg(errp, "No connection upgrade requested '%s'", connection);
434         goto bad_request;
435     }
436 
437     if (strcasecmp(upgrade, QIO_CHANNEL_WEBSOCK_UPGRADE_WEBSOCKET) != 0) {
438         error_setg(errp, "Incorrect upgrade method '%s'", upgrade);
439         goto bad_request;
440     }
441 
442     qio_channel_websock_handshake_send_res_ok(ioc, key, errp);
443     return;
444 
445  bad_request:
446     qio_channel_websock_handshake_send_res_err(
447         ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_BAD_REQUEST);
448 }
449 
450 static int qio_channel_websock_handshake_read(QIOChannelWebsock *ioc,
451                                               Error **errp)
452 {
453     char *handshake_end;
454     ssize_t ret;
455     /* Typical HTTP headers from novnc are 512 bytes, so limiting
456      * total header size to 4096 is easily enough. */
457     size_t want = 4096 - ioc->encinput.offset;
458     buffer_reserve(&ioc->encinput, want);
459     ret = qio_channel_read(ioc->master,
460                            (char *)buffer_end(&ioc->encinput), want, errp);
461     if (ret < 0) {
462         return -1;
463     }
464     ioc->encinput.offset += ret;
465 
466     handshake_end = g_strstr_len((char *)ioc->encinput.buffer,
467                                  ioc->encinput.offset,
468                                  QIO_CHANNEL_WEBSOCK_HANDSHAKE_END);
469     if (!handshake_end) {
470         if (ioc->encinput.offset >= 4096) {
471             qio_channel_websock_handshake_send_res_err(
472                 ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_TOO_LARGE);
473             error_setg(errp,
474                        "End of headers not found in first 4096 bytes");
475             return 1;
476         } else {
477             return 0;
478         }
479     }
480     *handshake_end = '\0';
481 
482     qio_channel_websock_handshake_process(ioc,
483                                           (char *)ioc->encinput.buffer,
484                                           errp);
485 
486     buffer_advance(&ioc->encinput,
487                    handshake_end - (char *)ioc->encinput.buffer +
488                    strlen(QIO_CHANNEL_WEBSOCK_HANDSHAKE_END));
489     return 1;
490 }
491 
492 static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc,
493                                                    GIOCondition condition,
494                                                    gpointer user_data)
495 {
496     QIOTask *task = user_data;
497     QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(
498         qio_task_get_source(task));
499     Error *err = NULL;
500     ssize_t ret;
501 
502     ret = qio_channel_write(wioc->master,
503                             (char *)wioc->encoutput.buffer,
504                             wioc->encoutput.offset,
505                             &err);
506 
507     if (ret < 0) {
508         trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err));
509         qio_task_set_error(task, err);
510         qio_task_complete(task);
511         return FALSE;
512     }
513 
514     buffer_advance(&wioc->encoutput, ret);
515     if (wioc->encoutput.offset == 0) {
516         if (wioc->io_err) {
517             trace_qio_channel_websock_handshake_fail(
518                 ioc, error_get_pretty(wioc->io_err));
519             qio_task_set_error(task, wioc->io_err);
520             wioc->io_err = NULL;
521             qio_task_complete(task);
522         } else {
523             trace_qio_channel_websock_handshake_complete(ioc);
524             qio_task_complete(task);
525         }
526         return FALSE;
527     }
528     trace_qio_channel_websock_handshake_pending(ioc, G_IO_OUT);
529     return TRUE;
530 }
531 
532 static gboolean qio_channel_websock_handshake_io(QIOChannel *ioc,
533                                                  GIOCondition condition,
534                                                  gpointer user_data)
535 {
536     QIOTask *task = user_data;
537     QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(
538         qio_task_get_source(task));
539     Error *err = NULL;
540     int ret;
541 
542     ret = qio_channel_websock_handshake_read(wioc, &err);
543     if (ret < 0) {
544         /*
545          * We only take this path on a fatal I/O error reading from
546          * client connection, as most of the time we have an
547          * HTTP 4xx err response to send instead
548          */
549         trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err));
550         qio_task_set_error(task, err);
551         qio_task_complete(task);
552         return FALSE;
553     }
554     if (ret == 0) {
555         trace_qio_channel_websock_handshake_pending(ioc, G_IO_IN);
556         /* need more data still */
557         return TRUE;
558     }
559 
560     if (err) {
561         error_propagate(&wioc->io_err, err);
562     }
563 
564     trace_qio_channel_websock_handshake_reply(ioc);
565     qio_channel_add_watch(
566         wioc->master,
567         G_IO_OUT,
568         qio_channel_websock_handshake_send,
569         task,
570         NULL);
571     return FALSE;
572 }
573 
574 
575 static void qio_channel_websock_encode(QIOChannelWebsock *ioc)
576 {
577     size_t header_size;
578     union {
579         char buf[QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT];
580         QIOChannelWebsockHeader ws;
581     } header;
582 
583     if (!ioc->rawoutput.offset) {
584         return;
585     }
586 
587     header.ws.b0 = QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN |
588         (QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME &
589          QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE);
590     if (ioc->rawoutput.offset <
591         QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_7_BIT) {
592         header.ws.b1 = (uint8_t)ioc->rawoutput.offset;
593         header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT;
594     } else if (ioc->rawoutput.offset <
595                QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_16_BIT) {
596         header.ws.b1 = QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT;
597         header.ws.u.s16.l16 = cpu_to_be16((uint16_t)ioc->rawoutput.offset);
598         header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT;
599     } else {
600         header.ws.b1 = QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_64_BIT;
601         header.ws.u.s64.l64 = cpu_to_be64(ioc->rawoutput.offset);
602         header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT;
603     }
604     header_size -= QIO_CHANNEL_WEBSOCK_HEADER_LEN_MASK;
605 
606     buffer_reserve(&ioc->encoutput, header_size + ioc->rawoutput.offset);
607     buffer_append(&ioc->encoutput, header.buf, header_size);
608     buffer_append(&ioc->encoutput, ioc->rawoutput.buffer,
609                   ioc->rawoutput.offset);
610     buffer_reset(&ioc->rawoutput);
611 }
612 
613 
614 static int qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
615                                              Error **errp)
616 {
617     unsigned char opcode, fin, has_mask;
618     size_t header_size;
619     size_t payload_len;
620     QIOChannelWebsockHeader *header =
621         (QIOChannelWebsockHeader *)ioc->encinput.buffer;
622 
623     if (ioc->payload_remain) {
624         error_setg(errp,
625                    "Decoding header but %zu bytes of payload remain",
626                    ioc->payload_remain);
627         return -1;
628     }
629     if (ioc->encinput.offset < QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT) {
630         /* header not complete */
631         return QIO_CHANNEL_ERR_BLOCK;
632     }
633 
634     fin = header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN;
635     opcode = header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE;
636     has_mask = header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK;
637     payload_len = header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN;
638 
639     /* Save or restore opcode. */
640     if (opcode) {
641         ioc->opcode = opcode;
642     } else {
643         opcode = ioc->opcode;
644     }
645 
646     if (opcode == QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE) {
647         /* disconnect */
648         return 0;
649     }
650 
651     /* Websocket frame sanity check:
652      * * Fragmentation is only supported for binary frames.
653      * * All frames sent by a client MUST be masked.
654      * * Only binary encoding is supported.
655      */
656     if (!fin) {
657         if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
658             error_setg(errp, "only binary websocket frames may be fragmented");
659             return -1;
660         }
661     } else {
662         if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
663             error_setg(errp, "only binary websocket frames are supported");
664             return -1;
665         }
666     }
667     if (!has_mask) {
668         error_setg(errp, "client websocket frames must be masked");
669         return -1;
670     }
671 
672     if (payload_len < QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT) {
673         ioc->payload_remain = payload_len;
674         header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT;
675         ioc->mask = header->u.m;
676     } else if (payload_len == QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT &&
677                ioc->encinput.offset >= QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT) {
678         ioc->payload_remain = be16_to_cpu(header->u.s16.l16);
679         header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT;
680         ioc->mask = header->u.s16.m16;
681     } else if (payload_len == QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_64_BIT &&
682                ioc->encinput.offset >= QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT) {
683         ioc->payload_remain = be64_to_cpu(header->u.s64.l64);
684         header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT;
685         ioc->mask = header->u.s64.m64;
686     } else {
687         /* header not complete */
688         return QIO_CHANNEL_ERR_BLOCK;
689     }
690 
691     buffer_advance(&ioc->encinput, header_size);
692     return 1;
693 }
694 
695 
696 static int qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
697                                               Error **errp)
698 {
699     size_t i;
700     size_t payload_len;
701     uint32_t *payload32;
702 
703     if (!ioc->payload_remain) {
704         error_setg(errp,
705                    "Decoding payload but no bytes of payload remain");
706         return -1;
707     }
708 
709     /* If we aren't at the end of the payload, then drop
710      * off the last bytes, so we're always multiple of 4
711      * for purpose of unmasking, except at end of payload
712      */
713     if (ioc->encinput.offset < ioc->payload_remain) {
714         payload_len = ioc->encinput.offset - (ioc->encinput.offset % 4);
715     } else {
716         payload_len = ioc->payload_remain;
717     }
718     if (payload_len == 0) {
719         return QIO_CHANNEL_ERR_BLOCK;
720     }
721 
722     ioc->payload_remain -= payload_len;
723 
724     /* unmask frame */
725     /* process 1 frame (32 bit op) */
726     payload32 = (uint32_t *)ioc->encinput.buffer;
727     for (i = 0; i < payload_len / 4; i++) {
728         payload32[i] ^= ioc->mask.u;
729     }
730     /* process the remaining bytes (if any) */
731     for (i *= 4; i < payload_len; i++) {
732         ioc->encinput.buffer[i] ^= ioc->mask.c[i % 4];
733     }
734 
735     buffer_reserve(&ioc->rawinput, payload_len);
736     buffer_append(&ioc->rawinput, ioc->encinput.buffer, payload_len);
737     buffer_advance(&ioc->encinput, payload_len);
738     return 0;
739 }
740 
741 
742 QIOChannelWebsock *
743 qio_channel_websock_new_server(QIOChannel *master)
744 {
745     QIOChannelWebsock *wioc;
746     QIOChannel *ioc;
747 
748     wioc = QIO_CHANNEL_WEBSOCK(object_new(TYPE_QIO_CHANNEL_WEBSOCK));
749     ioc = QIO_CHANNEL(wioc);
750 
751     wioc->master = master;
752     if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) {
753         qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
754     }
755     object_ref(OBJECT(master));
756 
757     trace_qio_channel_websock_new_server(wioc, master);
758     return wioc;
759 }
760 
761 void qio_channel_websock_handshake(QIOChannelWebsock *ioc,
762                                    QIOTaskFunc func,
763                                    gpointer opaque,
764                                    GDestroyNotify destroy)
765 {
766     QIOTask *task;
767 
768     task = qio_task_new(OBJECT(ioc),
769                         func,
770                         opaque,
771                         destroy);
772 
773     trace_qio_channel_websock_handshake_start(ioc);
774     trace_qio_channel_websock_handshake_pending(ioc, G_IO_IN);
775     qio_channel_add_watch(ioc->master,
776                           G_IO_IN,
777                           qio_channel_websock_handshake_io,
778                           task,
779                           NULL);
780 }
781 
782 
783 static void qio_channel_websock_finalize(Object *obj)
784 {
785     QIOChannelWebsock *ioc = QIO_CHANNEL_WEBSOCK(obj);
786 
787     buffer_free(&ioc->encinput);
788     buffer_free(&ioc->encoutput);
789     buffer_free(&ioc->rawinput);
790     buffer_free(&ioc->rawoutput);
791     object_unref(OBJECT(ioc->master));
792     if (ioc->io_tag) {
793         g_source_remove(ioc->io_tag);
794     }
795     if (ioc->io_err) {
796         error_free(ioc->io_err);
797     }
798 }
799 
800 
801 static ssize_t qio_channel_websock_read_wire(QIOChannelWebsock *ioc,
802                                              Error **errp)
803 {
804     ssize_t ret;
805 
806     if (ioc->encinput.offset < 4096) {
807         size_t want = 4096 - ioc->encinput.offset;
808 
809         buffer_reserve(&ioc->encinput, want);
810         ret = qio_channel_read(ioc->master,
811                                (char *)ioc->encinput.buffer +
812                                ioc->encinput.offset,
813                                want,
814                                errp);
815         if (ret < 0) {
816             return ret;
817         }
818         if (ret == 0 && ioc->encinput.offset == 0) {
819             ioc->io_eof = TRUE;
820             return 0;
821         }
822         ioc->encinput.offset += ret;
823     }
824 
825     while (ioc->encinput.offset != 0) {
826         if (ioc->payload_remain == 0) {
827             ret = qio_channel_websock_decode_header(ioc, errp);
828             if (ret < 0) {
829                 return ret;
830             }
831         }
832 
833         ret = qio_channel_websock_decode_payload(ioc, errp);
834         if (ret < 0) {
835             return ret;
836         }
837     }
838     return 1;
839 }
840 
841 
842 static ssize_t qio_channel_websock_write_wire(QIOChannelWebsock *ioc,
843                                               Error **errp)
844 {
845     ssize_t ret;
846     ssize_t done = 0;
847     qio_channel_websock_encode(ioc);
848 
849     while (ioc->encoutput.offset > 0) {
850         ret = qio_channel_write(ioc->master,
851                                 (char *)ioc->encoutput.buffer,
852                                 ioc->encoutput.offset,
853                                 errp);
854         if (ret < 0) {
855             if (ret == QIO_CHANNEL_ERR_BLOCK &&
856                 done > 0) {
857                 return done;
858             } else {
859                 return ret;
860             }
861         }
862         buffer_advance(&ioc->encoutput, ret);
863         done += ret;
864     }
865     return done;
866 }
867 
868 
869 static void qio_channel_websock_flush_free(gpointer user_data)
870 {
871     QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(user_data);
872     object_unref(OBJECT(wioc));
873 }
874 
875 static void qio_channel_websock_set_watch(QIOChannelWebsock *ioc);
876 
877 static gboolean qio_channel_websock_flush(QIOChannel *ioc,
878                                           GIOCondition condition,
879                                           gpointer user_data)
880 {
881     QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(user_data);
882     ssize_t ret;
883 
884     if (condition & G_IO_OUT) {
885         ret = qio_channel_websock_write_wire(wioc, &wioc->io_err);
886         if (ret < 0) {
887             goto cleanup;
888         }
889     }
890 
891     if (condition & G_IO_IN) {
892         ret = qio_channel_websock_read_wire(wioc, &wioc->io_err);
893         if (ret < 0) {
894             goto cleanup;
895         }
896     }
897 
898  cleanup:
899     qio_channel_websock_set_watch(wioc);
900     return FALSE;
901 }
902 
903 
904 static void qio_channel_websock_unset_watch(QIOChannelWebsock *ioc)
905 {
906     if (ioc->io_tag) {
907         g_source_remove(ioc->io_tag);
908         ioc->io_tag = 0;
909     }
910 }
911 
912 static void qio_channel_websock_set_watch(QIOChannelWebsock *ioc)
913 {
914     GIOCondition cond = 0;
915 
916     qio_channel_websock_unset_watch(ioc);
917 
918     if (ioc->io_err) {
919         return;
920     }
921 
922     if (ioc->encoutput.offset) {
923         cond |= G_IO_OUT;
924     }
925     if (ioc->encinput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER &&
926         !ioc->io_eof) {
927         cond |= G_IO_IN;
928     }
929 
930     if (cond) {
931         object_ref(OBJECT(ioc));
932         ioc->io_tag =
933             qio_channel_add_watch(ioc->master,
934                                   cond,
935                                   qio_channel_websock_flush,
936                                   ioc,
937                                   qio_channel_websock_flush_free);
938     }
939 }
940 
941 
942 static ssize_t qio_channel_websock_readv(QIOChannel *ioc,
943                                          const struct iovec *iov,
944                                          size_t niov,
945                                          int **fds,
946                                          size_t *nfds,
947                                          Error **errp)
948 {
949     QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);
950     size_t i;
951     ssize_t got = 0;
952     ssize_t ret;
953 
954     if (wioc->io_err) {
955         error_propagate(errp, error_copy(wioc->io_err));
956         return -1;
957     }
958 
959     if (!wioc->rawinput.offset) {
960         ret = qio_channel_websock_read_wire(QIO_CHANNEL_WEBSOCK(ioc), errp);
961         if (ret < 0) {
962             return ret;
963         }
964     }
965 
966     for (i = 0 ; i < niov ; i++) {
967         size_t want = iov[i].iov_len;
968         if (want > (wioc->rawinput.offset - got)) {
969             want = (wioc->rawinput.offset - got);
970         }
971 
972         memcpy(iov[i].iov_base,
973                wioc->rawinput.buffer + got,
974                want);
975         got += want;
976 
977         if (want < iov[i].iov_len) {
978             break;
979         }
980     }
981 
982     buffer_advance(&wioc->rawinput, got);
983     qio_channel_websock_set_watch(wioc);
984     return got;
985 }
986 
987 
988 static ssize_t qio_channel_websock_writev(QIOChannel *ioc,
989                                           const struct iovec *iov,
990                                           size_t niov,
991                                           int *fds,
992                                           size_t nfds,
993                                           Error **errp)
994 {
995     QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);
996     size_t i;
997     ssize_t done = 0;
998     ssize_t ret;
999 
1000     if (wioc->io_err) {
1001         error_propagate(errp, error_copy(wioc->io_err));
1002         return -1;
1003     }
1004 
1005     if (wioc->io_eof) {
1006         error_setg(errp, "%s", "Broken pipe");
1007         return -1;
1008     }
1009 
1010     for (i = 0; i < niov; i++) {
1011         size_t want = iov[i].iov_len;
1012         if ((want + wioc->rawoutput.offset) > QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
1013             want = (QIO_CHANNEL_WEBSOCK_MAX_BUFFER - wioc->rawoutput.offset);
1014         }
1015         if (want == 0) {
1016             goto done;
1017         }
1018 
1019         buffer_reserve(&wioc->rawoutput, want);
1020         buffer_append(&wioc->rawoutput, iov[i].iov_base, want);
1021         done += want;
1022         if (want < iov[i].iov_len) {
1023             break;
1024         }
1025     }
1026 
1027  done:
1028     ret = qio_channel_websock_write_wire(wioc, errp);
1029     if (ret < 0 &&
1030         ret != QIO_CHANNEL_ERR_BLOCK) {
1031         qio_channel_websock_unset_watch(wioc);
1032         return -1;
1033     }
1034 
1035     qio_channel_websock_set_watch(wioc);
1036 
1037     if (done == 0) {
1038         return QIO_CHANNEL_ERR_BLOCK;
1039     }
1040 
1041     return done;
1042 }
1043 
1044 static int qio_channel_websock_set_blocking(QIOChannel *ioc,
1045                                             bool enabled,
1046                                             Error **errp)
1047 {
1048     QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);
1049 
1050     qio_channel_set_blocking(wioc->master, enabled, errp);
1051     return 0;
1052 }
1053 
1054 static void qio_channel_websock_set_delay(QIOChannel *ioc,
1055                                           bool enabled)
1056 {
1057     QIOChannelWebsock *tioc = QIO_CHANNEL_WEBSOCK(ioc);
1058 
1059     qio_channel_set_delay(tioc->master, enabled);
1060 }
1061 
1062 static void qio_channel_websock_set_cork(QIOChannel *ioc,
1063                                          bool enabled)
1064 {
1065     QIOChannelWebsock *tioc = QIO_CHANNEL_WEBSOCK(ioc);
1066 
1067     qio_channel_set_cork(tioc->master, enabled);
1068 }
1069 
1070 static int qio_channel_websock_shutdown(QIOChannel *ioc,
1071                                         QIOChannelShutdown how,
1072                                         Error **errp)
1073 {
1074     QIOChannelWebsock *tioc = QIO_CHANNEL_WEBSOCK(ioc);
1075 
1076     return qio_channel_shutdown(tioc->master, how, errp);
1077 }
1078 
1079 static int qio_channel_websock_close(QIOChannel *ioc,
1080                                      Error **errp)
1081 {
1082     QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);
1083 
1084     return qio_channel_close(wioc->master, errp);
1085 }
1086 
1087 typedef struct QIOChannelWebsockSource QIOChannelWebsockSource;
1088 struct QIOChannelWebsockSource {
1089     GSource parent;
1090     QIOChannelWebsock *wioc;
1091     GIOCondition condition;
1092 };
1093 
1094 static gboolean
1095 qio_channel_websock_source_check(GSource *source)
1096 {
1097     QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source;
1098     GIOCondition cond = 0;
1099 
1100     if (wsource->wioc->rawinput.offset || wsource->wioc->io_eof) {
1101         cond |= G_IO_IN;
1102     }
1103     if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
1104         cond |= G_IO_OUT;
1105     }
1106 
1107     return cond & wsource->condition;
1108 }
1109 
1110 static gboolean
1111 qio_channel_websock_source_prepare(GSource *source,
1112                                    gint *timeout)
1113 {
1114     *timeout = -1;
1115     return qio_channel_websock_source_check(source);
1116 }
1117 
1118 static gboolean
1119 qio_channel_websock_source_dispatch(GSource *source,
1120                                     GSourceFunc callback,
1121                                     gpointer user_data)
1122 {
1123     QIOChannelFunc func = (QIOChannelFunc)callback;
1124     QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source;
1125 
1126     return (*func)(QIO_CHANNEL(wsource->wioc),
1127                    qio_channel_websock_source_check(source),
1128                    user_data);
1129 }
1130 
1131 static void
1132 qio_channel_websock_source_finalize(GSource *source)
1133 {
1134     QIOChannelWebsockSource *ssource = (QIOChannelWebsockSource *)source;
1135 
1136     object_unref(OBJECT(ssource->wioc));
1137 }
1138 
1139 GSourceFuncs qio_channel_websock_source_funcs = {
1140     qio_channel_websock_source_prepare,
1141     qio_channel_websock_source_check,
1142     qio_channel_websock_source_dispatch,
1143     qio_channel_websock_source_finalize
1144 };
1145 
1146 static GSource *qio_channel_websock_create_watch(QIOChannel *ioc,
1147                                                  GIOCondition condition)
1148 {
1149     QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);
1150     QIOChannelWebsockSource *ssource;
1151     GSource *source;
1152 
1153     source = g_source_new(&qio_channel_websock_source_funcs,
1154                           sizeof(QIOChannelWebsockSource));
1155     ssource = (QIOChannelWebsockSource *)source;
1156 
1157     ssource->wioc = wioc;
1158     object_ref(OBJECT(wioc));
1159 
1160     ssource->condition = condition;
1161 
1162     qio_channel_websock_set_watch(wioc);
1163     return source;
1164 }
1165 
1166 static void qio_channel_websock_class_init(ObjectClass *klass,
1167                                            void *class_data G_GNUC_UNUSED)
1168 {
1169     QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass);
1170 
1171     ioc_klass->io_writev = qio_channel_websock_writev;
1172     ioc_klass->io_readv = qio_channel_websock_readv;
1173     ioc_klass->io_set_blocking = qio_channel_websock_set_blocking;
1174     ioc_klass->io_set_cork = qio_channel_websock_set_cork;
1175     ioc_klass->io_set_delay = qio_channel_websock_set_delay;
1176     ioc_klass->io_close = qio_channel_websock_close;
1177     ioc_klass->io_shutdown = qio_channel_websock_shutdown;
1178     ioc_klass->io_create_watch = qio_channel_websock_create_watch;
1179 }
1180 
1181 static const TypeInfo qio_channel_websock_info = {
1182     .parent = TYPE_QIO_CHANNEL,
1183     .name = TYPE_QIO_CHANNEL_WEBSOCK,
1184     .instance_size = sizeof(QIOChannelWebsock),
1185     .instance_finalize = qio_channel_websock_finalize,
1186     .class_init = qio_channel_websock_class_init,
1187 };
1188 
1189 static void qio_channel_websock_register_types(void)
1190 {
1191     type_register_static(&qio_channel_websock_info);
1192 }
1193 
1194 type_init(qio_channel_websock_register_types);
1195