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