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