• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24 
25 #include <private-lib-core.h>
26 
27 #define LWS_CPYAPP(ptr, str) { strcpy(ptr, str); ptr += strlen(str); }
28 
29 #if !defined(LWS_WITHOUT_EXTENSIONS)
30 static int
lws_extension_server_handshake(struct lws * wsi,char ** p,int budget)31 lws_extension_server_handshake(struct lws *wsi, char **p, int budget)
32 {
33 	struct lws_context *context = wsi->a.context;
34 	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
35 	char ext_name[64], *args, *end = (*p) + budget - 1;
36 	const struct lws_ext_options *opts, *po;
37 	const struct lws_extension *ext;
38 	struct lws_ext_option_arg oa;
39 	int n, m, more = 1;
40 	int ext_count = 0;
41 	char ignore;
42 	char *c;
43 
44 	/*
45 	 * Figure out which extensions the client has that we want to
46 	 * enable on this connection, and give him back the list
47 	 */
48 	if (!lws_hdr_total_length(wsi, WSI_TOKEN_EXTENSIONS))
49 		return 0;
50 
51 	/*
52 	 * break down the list of client extensions
53 	 * and go through them
54 	 */
55 
56 	if (lws_hdr_copy(wsi, (char *)pt->serv_buf, (int)context->pt_serv_buf_size,
57 			 WSI_TOKEN_EXTENSIONS) < 0)
58 		return 1;
59 
60 	c = (char *)pt->serv_buf;
61 	lwsl_parser("WSI_TOKEN_EXTENSIONS = '%s'\n", c);
62 	wsi->ws->count_act_ext = 0;
63 	ignore = 0;
64 	n = 0;
65 	args = NULL;
66 
67 	/*
68 	 * We may get a simple request
69 	 *
70 	 * Sec-WebSocket-Extensions: permessage-deflate
71 	 *
72 	 * or an elaborated one with requested options
73 	 *
74 	 * Sec-WebSocket-Extensions: permessage-deflate; \
75 	 *			     server_no_context_takeover; \
76 	 *			     client_no_context_takeover
77 	 */
78 
79 	while (more) {
80 
81 		if (c >= (char *)pt->serv_buf + 255)
82 			return -1;
83 
84 		if (*c && (*c != ',' && *c != '\t')) {
85 			if (*c == ';') {
86 				ignore = 1;
87 				if (!args)
88 					args = c + 1;
89 			}
90 			if (ignore || *c == ' ') {
91 				c++;
92 				continue;
93 			}
94 			ext_name[n] = *c++;
95 			if (n < (int)sizeof(ext_name) - 1)
96 				n++;
97 			continue;
98 		}
99 		ext_name[n] = '\0';
100 
101 		ignore = 0;
102 		if (!*c)
103 			more = 0;
104 		else {
105 			c++;
106 			if (!n)
107 				continue;
108 		}
109 
110 		while (args && *args == ' ')
111 			args++;
112 
113 		/* check a client's extension against our support */
114 
115 		ext = wsi->a.vhost->ws.extensions;
116 
117 		while (ext && ext->callback) {
118 
119 			if (strcmp(ext_name, ext->name)) {
120 				ext++;
121 				continue;
122 			}
123 
124 			/*
125 			 * oh, we do support this one he asked for... but let's
126 			 * confirm he only gave it once
127 			 */
128 			for (m = 0; m < wsi->ws->count_act_ext; m++)
129 				if (wsi->ws->active_extensions[m] == ext) {
130 					lwsl_info("ext mentioned twice\n");
131 					return 1; /* shenanigans */
132 				}
133 
134 			/*
135 			 * ask user code if it's OK to apply it on this
136 			 * particular connection + protocol
137 			 */
138 			m = (wsi->a.protocol->callback)(wsi,
139 				LWS_CALLBACK_CONFIRM_EXTENSION_OKAY,
140 				wsi->user_space, ext_name, 0);
141 
142 			/*
143 			 * zero return from callback means go ahead and allow
144 			 * the extension, it's what we get if the callback is
145 			 * unhandled
146 			 */
147 			if (m) {
148 				ext++;
149 				continue;
150 			}
151 
152 			/* apply it */
153 
154 			ext_count++;
155 
156 			/* instantiate the extension on this conn */
157 
158 			wsi->ws->active_extensions[wsi->ws->count_act_ext] = ext;
159 
160 			/* allow him to construct his context */
161 
162 			if (ext->callback(lws_get_context(wsi), ext, wsi,
163 					  LWS_EXT_CB_CONSTRUCT,
164 					  (void *)&wsi->ws->act_ext_user[
165 					                wsi->ws->count_act_ext],
166 					  (void *)&opts, 0)) {
167 				lwsl_info("ext %s failed construction\n",
168 					    ext_name);
169 				ext_count--;
170 				ext++;
171 
172 				continue;
173 			}
174 
175 			if (ext_count > 1)
176 				*(*p)++ = ',';
177 			else
178 				LWS_CPYAPP(*p,
179 					  "\x0d\x0aSec-WebSocket-Extensions: ");
180 			*p += lws_snprintf(*p, lws_ptr_diff_size_t(end, *p), "%s", ext_name);
181 
182 			/*
183 			 * The client may send a bunch of different option
184 			 * sets for the same extension, we are supposed to
185 			 * pick one we like the look of.  The option sets are
186 			 * separated by comma.
187 			 *
188 			 * Actually we just either accept the first one or
189 			 * nothing.
190 			 *
191 			 * Go through the options trying to apply the
192 			 * recognized ones
193 			 */
194 
195 			lwsl_info("ext args %s\n", args);
196 
197 			while (args && *args && *args != ',') {
198 				while (*args == ' ')
199 					args++;
200 				po = opts;
201 				while (po->name) {
202 					/* only support arg-less options... */
203 					if (po->type != EXTARG_NONE ||
204 					    strncmp(args, po->name,
205 						    strlen(po->name))) {
206 						po++;
207 						continue;
208 					}
209 					oa.option_name = NULL;
210 					oa.option_index = (int)(po - opts);
211 					oa.start = NULL;
212 					oa.len = 0;
213 					lwsl_info("setting '%s'\n", po->name);
214 					if (!ext->callback(lws_get_context(wsi),
215 							   ext, wsi,
216 						LWS_EXT_CB_OPTION_SET,
217 						wsi->ws->act_ext_user[
218 							wsi->ws->count_act_ext],
219 							  &oa, lws_ptr_diff_size_t(end, *p))) {
220 
221 						*p += lws_snprintf(*p,
222 								   lws_ptr_diff_size_t(end, *p),
223 							      "; %s", po->name);
224 						lwsl_debug("adding option %s\n",
225 							   po->name);
226 					}
227 					po++;
228 				}
229 				while (*args && *args != ',' && *args != ';')
230 					args++;
231 
232 				if (*args == ';')
233 					args++;
234 			}
235 
236 			wsi->ws->count_act_ext++;
237 			lwsl_parser("cnt_act_ext <- %d\n",
238 				    wsi->ws->count_act_ext);
239 
240 			if (args && *args == ',')
241 				more = 0;
242 
243 			ext++;
244 		}
245 
246 		n = 0;
247 		args = NULL;
248 	}
249 
250 	return 0;
251 }
252 #endif
253 
254 int
lws_process_ws_upgrade2(struct lws * wsi)255 lws_process_ws_upgrade2(struct lws *wsi)
256 {
257 	struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
258 #if defined(LWS_WITH_HTTP_BASIC_AUTH)
259 	const struct lws_protocol_vhost_options *pvos = NULL;
260 	const char *ws_prot_basic_auth = NULL;
261 
262 
263 	/*
264 	 * Allow basic auth a look-in now we bound the wsi to the protocol.
265 	 *
266 	 * For vhost ws basic auth, it is "basic-auth": "path" as usual but
267 	 * applied to the protocol's entry in the vhost's "ws-protocols":
268 	 * section, as a pvo.
269 	 */
270 
271 	pvos = lws_vhost_protocol_options(wsi->a.vhost, wsi->a.protocol->name);
272 	if (pvos && pvos->options &&
273 	    !lws_pvo_get_str((void *)pvos->options, "basic-auth",
274 			     &ws_prot_basic_auth)) {
275 		lwsl_info("%s: ws upgrade requires basic auth\n", __func__);
276 		switch (lws_check_basic_auth(wsi, ws_prot_basic_auth, LWSAUTHM_DEFAULT
277 						/* no callback based auth here */)) {
278 		case LCBA_CONTINUE:
279 			break;
280 		case LCBA_FAILED_AUTH:
281 			return lws_unauthorised_basic_auth(wsi);
282 		case LCBA_END_TRANSACTION:
283 			lws_return_http_status(wsi, HTTP_STATUS_FORBIDDEN, NULL);
284 			return lws_http_transaction_completed(wsi);
285 		}
286 	}
287 #endif
288 
289 	/*
290 	 * We are upgrading to ws, so http/1.1 + h2 and keepalive + pipelined
291 	 * header considerations about keeping the ah around no longer apply.
292 	 *
293 	 * However it's common for the first ws protocol data to have been
294 	 * coalesced with the browser upgrade request and to already be in the
295 	 * ah rx buffer.
296 	 */
297 
298 	lws_pt_lock(pt, __func__);
299 
300 	/*
301 	 * Switch roles if we're upgrading away from http
302 	 */
303 
304 	if (!wsi->h2_stream_carries_ws) {
305 		lws_role_transition(wsi, LWSIFR_SERVER, LRS_ESTABLISHED,
306 				    &role_ops_ws);
307 
308 #if defined(LWS_WITH_SECURE_STREAMS) && defined(LWS_WITH_SERVER)
309 
310 		/*
311 		 * If we're a SS server object, we have to switch to ss-ws
312 		 * protocol handler too
313 		 */
314 		if (wsi->a.vhost->ss_handle) {
315 			lwsl_info("%s: %s switching to ws protocol\n",
316 				  __func__, lws_ss_tag(wsi->a.vhost->ss_handle));
317 			wsi->a.protocol = &protocol_secstream_ws;
318 
319 			/*
320 			 * inform the SS user code that this has done a one-way
321 			 * upgrade to some other protocol... it will likely
322 			 * want to treat subsequent payloads differently
323 			 */
324 
325 			(void)lws_ss_event_helper(wsi->a.vhost->ss_handle,
326 						LWSSSCS_SERVER_UPGRADE);
327 		}
328 #endif
329 	}
330 
331 	lws_pt_unlock(pt);
332 
333 	/* allocate the ws struct for the wsi */
334 
335 	wsi->ws = lws_zalloc(sizeof(*wsi->ws), "ws struct");
336 	if (!wsi->ws) {
337 		lwsl_notice("OOM\n");
338 		return 1;
339 	}
340 
341 	if (lws_hdr_total_length(wsi, WSI_TOKEN_VERSION))
342 		wsi->ws->ietf_spec_revision = (uint8_t)
343 			       atoi(lws_hdr_simple_ptr(wsi, WSI_TOKEN_VERSION));
344 
345 	/* allocate wsi->user storage */
346 	if (lws_ensure_user_space(wsi)) {
347 		lwsl_notice("problem with user space\n");
348 		return 1;
349 	}
350 
351 	/*
352 	 * Give the user code a chance to study the request and
353 	 * have the opportunity to deny it
354 	 */
355 	if ((wsi->a.protocol->callback)(wsi,
356 			LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
357 			wsi->user_space,
358 		      lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL), 0)) {
359 		lwsl_warn("User code denied connection\n");
360 		return 1;
361 	}
362 
363 	/*
364 	 * Perform the handshake according to the protocol version the
365 	 * client announced
366 	 */
367 
368 	switch (wsi->ws->ietf_spec_revision) {
369 	default:
370 		lwsl_notice("Unknown client spec version %d\n",
371 			  wsi->ws->ietf_spec_revision);
372 		wsi->ws->ietf_spec_revision = 13;
373 		//return 1;
374 		/* fallthru */
375 	case 13:
376 #if defined(LWS_WITH_HTTP2)
377 		if (wsi->h2_stream_carries_ws) {
378 			if (lws_h2_ws_handshake(wsi)) {
379 				lwsl_notice("h2 ws handshake failed\n");
380 				return 1;
381 			}
382 			lws_role_transition(wsi,
383 					    LWSIFR_SERVER | LWSIFR_P_ENCAP_H2,
384 					    LRS_ESTABLISHED, &role_ops_ws);
385 
386 			/*
387 			 * There should be no validity checking since we
388 			 * are encapsulated in something else with its own
389 			 * validity checking
390 			 */
391 
392 			lws_sul_cancel(&wsi->sul_validity);
393 		} else
394 #endif
395 		{
396 			lwsl_parser("lws_parse calling handshake_04\n");
397 			if (handshake_0405(wsi->a.context, wsi)) {
398 				lwsl_notice("hs0405 has failed the connection\n");
399 				return 1;
400 			}
401 		}
402 		break;
403 	}
404 
405 	if (lws_server_init_wsi_for_ws(wsi)) {
406 		lwsl_notice("%s: user ESTABLISHED failed connection\n", __func__);
407 		return 1;
408 	}
409 	lwsl_parser("accepted v%02d connection\n", wsi->ws->ietf_spec_revision);
410 
411 #if defined(LWS_WITH_ACCESS_LOG)
412 	{
413 		char *uptr = "unknown method", combo[128], dotstar[64];
414 		int l = 14, meth = lws_http_get_uri_and_method(wsi, &uptr, &l);
415 
416 		if (wsi->h2_stream_carries_ws)
417 			wsi->http.request_version = HTTP_VERSION_2;
418 
419 		wsi->http.access_log.response = 101;
420 
421 		lws_strnncpy(dotstar, uptr, l, sizeof(dotstar));
422 		l = lws_snprintf(combo, sizeof(combo), "%s (%s)", dotstar,
423 				 wsi->a.protocol->name);
424 
425 		if (meth < 0)
426 			meth = 0;
427 		lws_prepare_access_log_info(wsi, combo, l, meth);
428 		lws_access_log(wsi);
429 	}
430 #endif
431 
432 	lwsl_info("%s: %s: dropping ah on ws upgrade\n", __func__, lws_wsi_tag(wsi));
433 	lws_header_table_detach(wsi, 1);
434 
435 	return 0;
436 }
437 
438 int
lws_process_ws_upgrade(struct lws * wsi)439 lws_process_ws_upgrade(struct lws *wsi)
440 {
441 	const struct lws_protocols *pcol = NULL;
442 	char buf[128], name[64];
443 	struct lws_tokenize ts;
444 	lws_tokenize_elem e;
445 	int n;
446 
447 	if (!wsi->a.protocol)
448 		lwsl_err("NULL protocol at lws_read\n");
449 
450 	/*
451 	 * It's either websocket or h2->websocket
452 	 *
453 	 * If we are on h1, confirm we got the required "connection: upgrade"
454 	 * header.  h2 / ws-over-h2 does not have this.
455 	 */
456 
457 #if defined(LWS_WITH_HTTP2)
458 	if (!wsi->mux_substream) {
459 #endif
460 
461 		lws_tokenize_init(&ts, buf, LWS_TOKENIZE_F_COMMA_SEP_LIST |
462 					    LWS_TOKENIZE_F_DOT_NONTERM |
463 					    LWS_TOKENIZE_F_RFC7230_DELIMS |
464 					    LWS_TOKENIZE_F_MINUS_NONTERM);
465 		n = lws_hdr_copy(wsi, buf, sizeof(buf) - 1, WSI_TOKEN_CONNECTION);
466 		if (n <= 0)
467 			goto bad_conn_format;
468 		ts.len = (unsigned int)n;
469 
470 		do {
471 			e = lws_tokenize(&ts);
472 			switch (e) {
473 			case LWS_TOKZE_TOKEN:
474 				if (!strncasecmp(ts.token, "upgrade", ts.token_len))
475 					e = LWS_TOKZE_ENDED;
476 				break;
477 
478 			case LWS_TOKZE_DELIMITER:
479 				break;
480 
481 			default: /* includes ENDED */
482 	bad_conn_format:
483 				lwsl_err("%s: malformed or absent conn hdr\n",
484 					 __func__);
485 
486 				return 1;
487 			}
488 		} while (e > 0);
489 
490 #if defined(LWS_WITH_HTTP2)
491 	}
492 #endif
493 
494 #if defined(LWS_WITH_HTTP_PROXY)
495 	{
496 		const struct lws_http_mount *hit;
497 		int uri_len = 0, meth;
498 		char *uri_ptr;
499 
500 		meth = lws_http_get_uri_and_method(wsi, &uri_ptr, &uri_len);
501 		hit = lws_find_mount(wsi, uri_ptr, uri_len);
502 
503 		if (hit && (meth == LWSHUMETH_GET ||
504 			    meth == LWSHUMETH_CONNECT ||
505 			    meth == LWSHUMETH_COLON_PATH) &&
506 		    (hit->origin_protocol == LWSMPRO_HTTPS ||
507 		     hit->origin_protocol == LWSMPRO_HTTP))
508 			/*
509 			 * We are an h1 ws upgrade on a urlpath that corresponds
510 			 * to a proxying mount.  Don't try to deal with it
511 			 * locally, eg, we won't even have the right protocol
512 			 * handler since we're not the guy handling it, just a
513 			 * conduit.
514 			 *
515 			 * Instead open the related ongoing h1 connection
516 			 * according to the mount configuration and proxy
517 			 * whatever that has to say from now on.
518 			 */
519 			return lws_http_proxy_start(wsi, hit, uri_ptr, 1);
520 	}
521 #endif
522 
523 	/*
524 	 * Select the first protocol we support from the list
525 	 * the client sent us.
526 	 */
527 
528 	lws_tokenize_init(&ts, buf, LWS_TOKENIZE_F_COMMA_SEP_LIST |
529 				    LWS_TOKENIZE_F_MINUS_NONTERM |
530 				    LWS_TOKENIZE_F_DOT_NONTERM |
531 				    LWS_TOKENIZE_F_RFC7230_DELIMS);
532 	n = lws_hdr_copy(wsi, buf, sizeof(buf) - 1, WSI_TOKEN_PROTOCOL);
533 	if (n < 0) {
534 		lwsl_err("%s: protocol list too long\n", __func__);
535 		return 1;
536 	}
537 	ts.len = (unsigned int)n;
538 	if (!ts.len) {
539 		int n = wsi->a.vhost->default_protocol_index;
540 		/*
541 		 * Some clients only have one protocol and do not send the
542 		 * protocol list header... allow it and match to the vhost's
543 		 * default protocol (which itself defaults to zero).
544 		 *
545 		 * Setting the vhost default protocol index to -1 or anything
546 		 * more than the actual number of protocols on the vhost causes
547 		 * these "no protocol" ws connections to be rejected.
548 		 */
549 
550 		if (n >= wsi->a.vhost->count_protocols) {
551 			lwsl_notice("%s: rejecting ws upg with no protocol\n",
552 				    __func__);
553 
554 			return 1;
555 		}
556 
557 		lwsl_info("%s: defaulting to prot handler %d\n", __func__, n);
558 
559 		lws_bind_protocol(wsi, &wsi->a.vhost->protocols[n],
560 				  "ws upgrade default pcol");
561 
562 		goto alloc_ws;
563 	}
564 
565 #if defined(LWS_WITH_SECURE_STREAMS) && defined(LWS_WITH_SERVER)
566 	if (wsi->a.vhost->ss_handle) {
567 		lws_ss_handle_t *sssh = wsi->a.vhost->ss_handle;
568 
569 		/*
570 		 * At the moment, once we see it's a ss ws server, whatever
571 		 * he asked for we bind him to the ss-ws protocol handler.
572 		 *
573 		 * In the response subprotocol header, we need to name
574 		 *
575 		 * sssh->policy->u.http.u.ws.subprotocol
576 		 *
577 		 * though...
578 		 */
579 
580 		if (sssh->policy->u.http.u.ws.subprotocol) {
581 			pcol = lws_vhost_name_to_protocol(wsi->a.vhost,
582 							  "lws-secstream-ws");
583 			if (pcol) {
584 				lws_bind_protocol(wsi, pcol, "ss ws upg pcol");
585 
586 				goto alloc_ws;
587 			}
588 		}
589 	}
590 #endif
591 
592 	/* otherwise go through the user-provided protocol list */
593 
594 	do {
595 		e = lws_tokenize(&ts);
596 		switch (e) {
597 		case LWS_TOKZE_TOKEN:
598 
599 			if (lws_tokenize_cstr(&ts, name, sizeof(name))) {
600 				lwsl_err("%s: pcol name too long\n", __func__);
601 
602 				return 1;
603 			}
604 			lwsl_debug("checking %s\n", name);
605 			pcol = lws_vhost_name_to_protocol(wsi->a.vhost, name);
606 			if (pcol) {
607 				/* if we know it, bind to it and stop looking */
608 				lws_bind_protocol(wsi, pcol, "ws upg pcol");
609 				e = LWS_TOKZE_ENDED;
610 			}
611 			break;
612 
613 		case LWS_TOKZE_DELIMITER:
614 		case LWS_TOKZE_ENDED:
615 			break;
616 
617 		default:
618 			lwsl_err("%s: malformatted protocol list", __func__);
619 
620 			return 1;
621 		}
622 	} while (e > 0);
623 
624 	/* we didn't find a protocol he wanted? */
625 
626 	if (!pcol) {
627 		lwsl_notice("No supported protocol \"%s\"\n", buf);
628 
629 		return 1;
630 	}
631 
632 alloc_ws:
633 
634 	return lws_process_ws_upgrade2(wsi);
635 }
636 
637 int
handshake_0405(struct lws_context * context,struct lws * wsi)638 handshake_0405(struct lws_context *context, struct lws *wsi)
639 {
640 	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
641 	struct lws_process_html_args args;
642 	unsigned char hash[20];
643 	int n, accept_len;
644 	char *response;
645 	char *p;
646 
647 	if (!lws_hdr_total_length(wsi, WSI_TOKEN_HOST) ||
648 	    !lws_hdr_total_length(wsi, WSI_TOKEN_KEY)) {
649 		lwsl_info("handshake_04 missing pieces\n");
650 		/* completed header processing, but missing some bits */
651 		goto bail;
652 	}
653 
654 	if (lws_hdr_total_length(wsi, WSI_TOKEN_KEY) >=
655 	    MAX_WEBSOCKET_04_KEY_LEN) {
656 		lwsl_warn("Client key too long %d\n", MAX_WEBSOCKET_04_KEY_LEN);
657 		goto bail;
658 	}
659 
660 	/*
661 	 * since key length is restricted above (currently 128), cannot
662 	 * overflow
663 	 */
664 	n = sprintf((char *)pt->serv_buf,
665 		    "%s258EAFA5-E914-47DA-95CA-C5AB0DC85B11",
666 		    lws_hdr_simple_ptr(wsi, WSI_TOKEN_KEY));
667 
668 	lws_SHA1(pt->serv_buf, (unsigned int)n, hash);
669 
670 	accept_len = lws_b64_encode_string((char *)hash, 20,
671 			(char *)pt->serv_buf, (int)context->pt_serv_buf_size);
672 	if (accept_len < 0) {
673 		lwsl_warn("Base64 encoded hash too long\n");
674 		goto bail;
675 	}
676 
677 	/* allocate the per-connection user memory (if any) */
678 	if (lws_ensure_user_space(wsi))
679 		goto bail;
680 
681 	/* create the response packet */
682 
683 	/* make a buffer big enough for everything */
684 
685 	response = (char *)pt->serv_buf + MAX_WEBSOCKET_04_KEY_LEN +
686 		   256 + LWS_PRE;
687 	p = response;
688 	LWS_CPYAPP(p, "HTTP/1.1 101 Switching Protocols\x0d\x0a"
689 		      "Upgrade: WebSocket\x0d\x0a"
690 		      "Connection: Upgrade\x0d\x0a"
691 		      "Sec-WebSocket-Accept: ");
692 	strcpy(p, (char *)pt->serv_buf);
693 	p += accept_len;
694 
695 	/* we can only return the protocol header if:
696 	 *  - one came in, and ... */
697 	if (lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL) &&
698 	    /*  - it is not an empty string */
699 	    wsi->a.protocol->name &&
700 	    wsi->a.protocol->name[0]) {
701 		const char *prot = wsi->a.protocol->name;
702 
703 #if defined(LWS_WITH_HTTP_PROXY)
704 		if (wsi->proxied_ws_parent && wsi->child_list)
705 			prot = wsi->child_list->ws->actual_protocol;
706 #endif
707 
708 #if defined(LWS_WITH_SECURE_STREAMS) && defined(LWS_WITH_SERVER)
709 		{
710 			lws_ss_handle_t *sssh = wsi->a.vhost->ss_handle;
711 
712 			/*
713 			 * At the moment, once we see it's a ss ws server, whatever
714 			 * he asked for we bind him to the ss-ws protocol handler.
715 			 *
716 			 * In the response subprotocol header, we need to name
717 			 *
718 			 * sssh->policy->u.http.u.ws.subprotocol
719 			 *
720 			 * though...
721 			 */
722 
723 			if (sssh && sssh->policy &&
724 			    sssh->policy->u.http.u.ws.subprotocol)
725 				prot = sssh->policy->u.http.u.ws.subprotocol;
726 		}
727 #endif
728 
729 		LWS_CPYAPP(p, "\x0d\x0aSec-WebSocket-Protocol: ");
730 		p += lws_snprintf(p, 128, "%s", prot);
731 	}
732 
733 #if !defined(LWS_WITHOUT_EXTENSIONS)
734 	/*
735 	 * Figure out which extensions the client has that we want to
736 	 * enable on this connection, and give him back the list.
737 	 *
738 	 * Give him a limited write bugdet
739 	 */
740 	if (lws_extension_server_handshake(wsi, &p, 192))
741 		goto bail;
742 #endif
743 	LWS_CPYAPP(p, "\x0d\x0a");
744 
745 	args.p = p;
746 	args.max_len = lws_ptr_diff((char *)pt->serv_buf +
747 				    context->pt_serv_buf_size, p);
748 	if (user_callback_handle_rxflow(wsi->a.protocol->callback, wsi,
749 					LWS_CALLBACK_ADD_HEADERS,
750 					wsi->user_space, &args, 0))
751 		goto bail;
752 
753 	p = args.p;
754 
755 	/* end of response packet */
756 
757 	LWS_CPYAPP(p, "\x0d\x0a");
758 
759 	/* okay send the handshake response accepting the connection */
760 
761 	lwsl_parser("issuing resp pkt %d len\n",
762 		    lws_ptr_diff(p, response));
763 #if defined(DEBUG)
764 	fwrite(response, 1,  p - response, stderr);
765 #endif
766 	n = lws_write(wsi, (unsigned char *)response, lws_ptr_diff_size_t(p, response),
767 		      LWS_WRITE_HTTP_HEADERS);
768 	if (n != lws_ptr_diff(p, response)) {
769 		lwsl_info("%s: ERROR writing to socket %d\n", __func__, n);
770 		goto bail;
771 	}
772 
773 	/* alright clean up and set ourselves into established state */
774 
775 	lwsi_set_state(wsi, LRS_ESTABLISHED);
776 	wsi->lws_rx_parse_state = LWS_RXPS_NEW;
777 
778 	{
779 		const char * uri_ptr =
780 			lws_hdr_simple_ptr(wsi, WSI_TOKEN_GET_URI);
781 		int uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI);
782 		const struct lws_http_mount *hit =
783 			lws_find_mount(wsi, uri_ptr, uri_len);
784 		if (hit && hit->cgienv &&
785 		    wsi->a.protocol->callback(wsi, LWS_CALLBACK_HTTP_PMO,
786 			wsi->user_space, (void *)hit->cgienv, 0))
787 			return 1;
788 	}
789 
790 	return 0;
791 
792 bail:
793 	/* caller will free up his parsing allocations */
794 	return -1;
795 }
796 
797 
798 
799 /*
800  * Once we reach LWS_RXPS_WS_FRAME_PAYLOAD, we know how much
801  * to expect in that state and can deal with it in bulk more efficiently.
802  */
803 
804 static int
lws_ws_frame_rest_is_payload(struct lws * wsi,uint8_t ** buf,size_t len)805 lws_ws_frame_rest_is_payload(struct lws *wsi, uint8_t **buf, size_t len)
806 {
807 	struct lws_ext_pm_deflate_rx_ebufs pmdrx;
808 	unsigned int avail = (unsigned int)len;
809 	uint8_t *buffer = *buf, mask[4];
810 #if !defined(LWS_WITHOUT_EXTENSIONS)
811 	unsigned int old_packet_length = (unsigned int)wsi->ws->rx_packet_length;
812 #endif
813 	int n = 0;
814 
815 	/*
816 	 * With zlib, we can give it as much input as we like.  The pmd
817 	 * extension will draw it down in chunks (default 1024).
818 	 *
819 	 * If we try to restrict how much we give it, because we must go
820 	 * back to the event loop each time, we will drop the remainder...
821 	 */
822 
823 #if !defined(LWS_WITHOUT_EXTENSIONS)
824 	if (!wsi->ws->count_act_ext)
825 #endif
826 	{
827 		if (wsi->a.protocol->rx_buffer_size)
828 			avail = (unsigned int)wsi->a.protocol->rx_buffer_size;
829 		else
830 			avail = wsi->a.context->pt_serv_buf_size;
831 	}
832 
833 	/* do not consume more than we should */
834 	if (avail > wsi->ws->rx_packet_length)
835 		avail = (unsigned int)wsi->ws->rx_packet_length;
836 
837 	/* do not consume more than what is in the buffer */
838 	if (avail > len)
839 		avail = (unsigned int)len;
840 
841 	if (!avail)
842 		return 0;
843 
844 	pmdrx.eb_in.token = buffer;
845 	pmdrx.eb_in.len = (int)avail;
846 	pmdrx.eb_out.token = buffer;
847 	pmdrx.eb_out.len = (int)avail;
848 
849 	if (!wsi->ws->all_zero_nonce) {
850 
851 		for (n = 0; n < 4; n++)
852 			mask[n] = wsi->ws->mask[(wsi->ws->mask_idx + n) & 3];
853 
854 		/* deal with 4-byte chunks using unwrapped loop */
855 		n = (int)(avail >> 2);
856 		while (n--) {
857 			*(buffer) = *(buffer) ^ mask[0];
858 			buffer++;
859 			*(buffer) = *(buffer) ^ mask[1];
860 			buffer++;
861 			*(buffer) = *(buffer) ^ mask[2];
862 			buffer++;
863 			*(buffer) = *(buffer) ^ mask[3];
864 			buffer++;
865 		}
866 		/* and the remaining bytes bytewise */
867 		for (n = 0; n < (int)(avail & 3); n++) {
868 			*(buffer) = *(buffer) ^ mask[n];
869 			buffer++;
870 		}
871 
872 		wsi->ws->mask_idx = (wsi->ws->mask_idx + avail) & 3;
873 	}
874 
875 	lwsl_info("%s: using %d of raw input (total %d on offer)\n", __func__,
876 		    avail, (int)len);
877 
878 	(*buf) += avail;
879 	len -= avail;
880 	wsi->ws->rx_packet_length -= avail;
881 
882 #if !defined(LWS_WITHOUT_EXTENSIONS)
883 	n = lws_ext_cb_active(wsi, LWS_EXT_CB_PAYLOAD_RX, &pmdrx, 0);
884 	lwsl_info("%s: ext says %d / ebuf_out.len %d\n", __func__,  n,
885 			pmdrx.eb_out.len);
886 
887 	/*
888 	 * ebuf may be pointing somewhere completely different now,
889 	 * it's the output
890 	 */
891 
892 	if (n < 0) {
893 		/*
894 		 * we may rely on this to get RX, just drop connection
895 		 */
896 		lwsl_notice("%s: LWS_EXT_CB_PAYLOAD_RX blew out\n", __func__);
897 		wsi->socket_is_permanently_unusable = 1;
898 
899 		return -1;
900 	}
901 
902 	/*
903 	 * if we had an rx fragment right at the last compressed byte of the
904 	 * message, we can get a zero length inflated output, where no prior
905 	 * rx inflated output marked themselves with FIN, since there was
906 	 * raw ws payload still to drain at that time.
907 	 *
908 	 * Then we need to generate a zero length ws rx that can be understood
909 	 * as the message completion.
910 	 */
911 
912 	if (!pmdrx.eb_out.len &&	      /* zero-length inflation output */
913 	    n == PMDR_EMPTY_FINAL &&    /* nothing to drain from the inflator */
914 	    old_packet_length &&	    /* we gave the inflator new input */
915 	    !wsi->ws->rx_packet_length &&   /* raw ws packet payload all gone */
916 	    wsi->ws->final &&		    /* the raw ws packet is a FIN guy */
917 	    wsi->a.protocol->callback &&
918 	    !wsi->wsistate_pre_close) {
919 
920 		lwsl_ext("%s: issuing zero length FIN pkt\n", __func__);
921 
922 		if (user_callback_handle_rxflow(wsi->a.protocol->callback, wsi,
923 						LWS_CALLBACK_RECEIVE,
924 						wsi->user_space, NULL, 0))
925 			return -1;
926 
927 		return (int)avail;
928 	}
929 
930 	/*
931 	 * If doing permessage-deflate, above was the only way to get a zero
932 	 * length receive.  Otherwise we're more willing.
933 	 */
934 	if (wsi->ws->count_act_ext && !pmdrx.eb_out.len)
935 		return (int)avail;
936 
937 	if (n == PMDR_HAS_PENDING)
938 		/* extension had more... main loop will come back */
939 		lws_add_wsi_to_draining_ext_list(wsi);
940 	else
941 		lws_remove_wsi_from_draining_ext_list(wsi);
942 #endif
943 
944 	if (pmdrx.eb_out.len &&
945 	    wsi->ws->check_utf8 && !wsi->ws->defeat_check_utf8) {
946 		if (lws_check_utf8(&wsi->ws->utf8,
947 				   pmdrx.eb_out.token,
948 				   (unsigned int)pmdrx.eb_out.len)) {
949 			lws_close_reason(wsi, LWS_CLOSE_STATUS_INVALID_PAYLOAD,
950 					 (uint8_t *)"bad utf8", 8);
951 			goto utf8_fail;
952 		}
953 
954 		/* we are ending partway through utf-8 character? */
955 		if (!wsi->ws->rx_packet_length && wsi->ws->final &&
956 		    wsi->ws->utf8 && !n) {
957 			lwsl_info("FINAL utf8 error\n");
958 			lws_close_reason(wsi, LWS_CLOSE_STATUS_INVALID_PAYLOAD,
959 					 (uint8_t *)"partial utf8", 12);
960 
961 utf8_fail:
962 			lwsl_info("utf8 error\n");
963 			lwsl_hexdump_info(pmdrx.eb_out.token, (size_t)pmdrx.eb_out.len);
964 
965 			return -1;
966 		}
967 	}
968 
969 	if (wsi->a.protocol->callback && !wsi->wsistate_pre_close)
970 		if (user_callback_handle_rxflow(wsi->a.protocol->callback, wsi,
971 						LWS_CALLBACK_RECEIVE,
972 						wsi->user_space,
973 						pmdrx.eb_out.token,
974 						(unsigned int)pmdrx.eb_out.len))
975 			return -1;
976 
977 	wsi->ws->first_fragment = 0;
978 
979 #if !defined(LWS_WITHOUT_EXTENSIONS)
980 	lwsl_info("%s: input used %d, output %d, rem len %d, rx_draining_ext %d\n",
981 		  __func__, avail, pmdrx.eb_out.len, (int)len,
982 		  wsi->ws->rx_draining_ext);
983 #endif
984 
985 	return (int)avail; /* how much we used from the input */
986 }
987 
988 
989 int
lws_parse_ws(struct lws * wsi,unsigned char ** buf,size_t len)990 lws_parse_ws(struct lws *wsi, unsigned char **buf, size_t len)
991 {
992 	unsigned char *bufin = *buf;
993 	int m, bulk = 0;
994 
995 	lwsl_debug("%s: received %d byte packet\n", __func__, (int)len);
996 
997 	//lwsl_hexdump_notice(*buf, len);
998 
999 	/* let the rx protocol state machine have as much as it needs */
1000 
1001 	while (len) {
1002 		/*
1003 		 * we were accepting input but now we stopped doing so
1004 		 */
1005 		if (wsi->rxflow_bitmap) {
1006 			lwsl_info("%s: doing rxflow, caching %d\n", __func__,
1007 				(int)len);
1008 			/*
1009 			 * Since we cached the remaining available input, we
1010 			 * can say we "consumed" it.
1011 			 *
1012 			 * But what about the case where the available input
1013 			 * came out of the rxflow cache already?  If we are
1014 			 * effectively "putting it back in the cache", we have
1015 			 * leave it where it is, already pointed to by the head.
1016 			 */
1017 			if (lws_rxflow_cache(wsi, *buf, 0, len) ==
1018 							LWSRXFC_TRIMMED) {
1019 				/*
1020 				 * We dealt with it by trimming the existing
1021 				 * rxflow cache HEAD to account for what we used.
1022 				 *
1023 				 * so he doesn't do any consumed processing
1024 				 */
1025 				lwsl_info("%s: trimming inside rxflow cache\n",
1026 					  __func__);
1027 				*buf = bufin;
1028 			} else
1029 				*buf += len;
1030 
1031 			return 1;
1032 		}
1033 #if !defined(LWS_WITHOUT_EXTENSIONS)
1034 		if (wsi->ws->rx_draining_ext) {
1035 			lwsl_debug("%s: draining rx ext\n", __func__);
1036 			m = lws_ws_rx_sm(wsi, ALREADY_PROCESSED_IGNORE_CHAR, 0);
1037 			if (m < 0)
1038 				return -1;
1039 			continue;
1040 		}
1041 #endif
1042 
1043 		/* consume payload bytes efficiently */
1044 		while (wsi->lws_rx_parse_state == LWS_RXPS_WS_FRAME_PAYLOAD &&
1045 				(wsi->ws->opcode == LWSWSOPC_TEXT_FRAME ||
1046 				 wsi->ws->opcode == LWSWSOPC_BINARY_FRAME ||
1047 				 wsi->ws->opcode == LWSWSOPC_CONTINUATION) &&
1048 		       len) {
1049 			uint8_t *bin = *buf;
1050 
1051 			bulk = 1;
1052 			m = lws_ws_frame_rest_is_payload(wsi, buf, len);
1053 			assert((int)lws_ptr_diff(*buf, bin) <= (int)len);
1054 			len -= lws_ptr_diff_size_t(*buf, bin);
1055 
1056 			if (!m) {
1057 
1058 				break;
1059 			}
1060 			if (m < 0) {
1061 				lwsl_info("%s: rest_is_payload bailed\n",
1062 					  __func__);
1063 				return -1;
1064 			}
1065 		}
1066 
1067 		if (!bulk) {
1068 			/* process the byte */
1069 			m = lws_ws_rx_sm(wsi, 0, *(*buf)++);
1070 			len--;
1071 		} else {
1072 			/*
1073 			 * We already handled this byte in bulk, just deal
1074 			 * with the ramifications
1075 			 */
1076 #if !defined(LWS_WITHOUT_EXTENSIONS)
1077 			lwsl_debug("%s: coming out of bulk with len %d, "
1078 				   "wsi->ws->rx_draining_ext %d\n",
1079 				   __func__, (int)len,
1080 				   wsi->ws->rx_draining_ext);
1081 #endif
1082 			m = lws_ws_rx_sm(wsi, ALREADY_PROCESSED_IGNORE_CHAR |
1083 					      ALREADY_PROCESSED_NO_CB, 0);
1084 		}
1085 
1086 		if (m < 0) {
1087 			lwsl_info("%s: lws_ws_rx_sm bailed %d\n", __func__,
1088 				  bulk);
1089 
1090 			return -1;
1091 		}
1092 
1093 		bulk = 0;
1094 	}
1095 
1096 	lwsl_debug("%s: exit with %d unused\n", __func__, (int)len);
1097 
1098 	return 0;
1099 }
1100