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 (strcasecmp(connection, QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE) != 0) { 435 error_setg(errp, "No connection upgrade requested '%s'", connection); 436 goto bad_request; 437 } 438 439 if (strcasecmp(upgrade, QIO_CHANNEL_WEBSOCK_UPGRADE_WEBSOCKET) != 0) { 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