Fix to expose openssl dependency
[platform/upstream/libwebsockets.git] / lib / client-parser.c
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010-2014 Andy Green <andy@warmcat.com>
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:
9  *  version 2.1 of the License.
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, write to the Free Software
18  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  *  MA  02110-1301  USA
20  */
21
22 #include "private-libwebsockets.h"
23
24 /*
25  * parsers.c: lws_rx_sm() needs to be roughly kept in
26  *   sync with changes here, esp related to ext draining
27  */
28
29 int lws_client_rx_sm(struct lws *wsi, unsigned char c)
30 {
31         int callback_action = LWS_CALLBACK_CLIENT_RECEIVE;
32         int handled, n, m, rx_draining_ext = 0;
33         unsigned short close_code;
34         struct lws_tokens eff_buf;
35         unsigned char *pp;
36
37         if (wsi->u.ws.rx_draining_ext) {
38                 assert(!c);
39                 eff_buf.token = NULL;
40                 eff_buf.token_len = 0;
41                 lws_remove_wsi_from_draining_ext_list(wsi);
42                 rx_draining_ext = 1;
43                 lwsl_debug("%s: doing draining flow\n", __func__);
44
45                 goto drain_extension;
46         }
47
48         if (wsi->socket_is_permanently_unusable)
49                 return -1;
50
51         switch (wsi->lws_rx_parse_state) {
52         case LWS_RXPS_NEW:
53                 /* control frames (PING) may interrupt checkable sequences */
54                 wsi->u.ws.defeat_check_utf8 = 0;
55
56                 switch (wsi->ietf_spec_revision) {
57                 case 13:
58                         wsi->u.ws.opcode = c & 0xf;
59                         /* revisit if an extension wants them... */
60                         switch (wsi->u.ws.opcode) {
61                         case LWSWSOPC_TEXT_FRAME:
62                                 wsi->u.ws.rsv_first_msg = (c & 0x70);
63                                 wsi->u.ws.continuation_possible = 1;
64                                 wsi->u.ws.check_utf8 = lws_check_opt(
65                                         wsi->context->options,
66                                         LWS_SERVER_OPTION_VALIDATE_UTF8);
67                                 wsi->u.ws.utf8 = 0;
68                                 break;
69                         case LWSWSOPC_BINARY_FRAME:
70                                 wsi->u.ws.rsv_first_msg = (c & 0x70);
71                                 wsi->u.ws.check_utf8 = 0;
72                                 wsi->u.ws.continuation_possible = 1;
73                                 break;
74                         case LWSWSOPC_CONTINUATION:
75                                 if (!wsi->u.ws.continuation_possible) {
76                                         lwsl_info("disordered continuation\n");
77                                         return -1;
78                                 }
79                                 break;
80                         case LWSWSOPC_CLOSE:
81                                 wsi->u.ws.check_utf8 = 0;
82                                 wsi->u.ws.utf8 = 0;
83                                 break;
84                         case 3:
85                         case 4:
86                         case 5:
87                         case 6:
88                         case 7:
89                         case 0xb:
90                         case 0xc:
91                         case 0xd:
92                         case 0xe:
93                         case 0xf:
94                                 lwsl_info("illegal opcode\n");
95                                 return -1;
96                         default:
97                                 wsi->u.ws.defeat_check_utf8 = 1;
98                                 break;
99                         }
100                         wsi->u.ws.rsv = (c & 0x70);
101                         /* revisit if an extension wants them... */
102                         if (
103 #ifndef LWS_NO_EXTENSIONS
104                                 !wsi->count_act_ext &&
105 #endif
106                                 wsi->u.ws.rsv) {
107                                 lwsl_info("illegal rsv bits set\n");
108                                 return -1;
109                         }
110                         wsi->u.ws.final = !!((c >> 7) & 1);
111                         lwsl_ext("%s:    This RX frame Final %d\n", __func__, wsi->u.ws.final);
112
113                         if (wsi->u.ws.owed_a_fin &&
114                             (wsi->u.ws.opcode == LWSWSOPC_TEXT_FRAME ||
115                              wsi->u.ws.opcode == LWSWSOPC_BINARY_FRAME)) {
116                                 lwsl_info("hey you owed us a FIN\n");
117                                 return -1;
118                         }
119                         if ((!(wsi->u.ws.opcode & 8)) && wsi->u.ws.final) {
120                                 wsi->u.ws.continuation_possible = 0;
121                                 wsi->u.ws.owed_a_fin = 0;
122                         }
123
124                         if ((wsi->u.ws.opcode & 8) && !wsi->u.ws.final) {
125                                 lwsl_info("control message cannot be fragmented\n");
126                                 return -1;
127                         }
128                         if (!wsi->u.ws.final)
129                                 wsi->u.ws.owed_a_fin = 1;
130
131                         switch (wsi->u.ws.opcode) {
132                         case LWSWSOPC_TEXT_FRAME:
133                         case LWSWSOPC_BINARY_FRAME:
134                                 wsi->u.ws.frame_is_binary = wsi->u.ws.opcode ==
135                                                  LWSWSOPC_BINARY_FRAME;
136                                 break;
137                         }
138                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
139                         break;
140
141                 default:
142                         lwsl_err("unknown spec version %02d\n",
143                                                        wsi->ietf_spec_revision);
144                         break;
145                 }
146                 break;
147
148         case LWS_RXPS_04_FRAME_HDR_LEN:
149
150                 wsi->u.ws.this_frame_masked = !!(c & 0x80);
151
152                 switch (c & 0x7f) {
153                 case 126:
154                         /* control frames are not allowed to have big lengths */
155                         if (wsi->u.ws.opcode & 8)
156                                 goto illegal_ctl_length;
157                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2;
158                         break;
159                 case 127:
160                         /* control frames are not allowed to have big lengths */
161                         if (wsi->u.ws.opcode & 8)
162                                 goto illegal_ctl_length;
163                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
164                         break;
165                 default:
166                         wsi->u.ws.rx_packet_length = c;
167                         if (wsi->u.ws.this_frame_masked)
168                                 wsi->lws_rx_parse_state =
169                                                 LWS_RXPS_07_COLLECT_FRAME_KEY_1;
170                         else {
171                                 if (c)
172                                         wsi->lws_rx_parse_state =
173                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
174                                 else {
175                                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
176                                         goto spill;
177                                 }
178                         }
179                         break;
180                 }
181                 break;
182
183         case LWS_RXPS_04_FRAME_HDR_LEN16_2:
184                 wsi->u.ws.rx_packet_length = c << 8;
185                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1;
186                 break;
187
188         case LWS_RXPS_04_FRAME_HDR_LEN16_1:
189                 wsi->u.ws.rx_packet_length |= c;
190                 if (wsi->u.ws.this_frame_masked)
191                         wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_1;
192                 else {
193                         if (wsi->u.ws.rx_packet_length)
194                                 wsi->lws_rx_parse_state =
195                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
196                         else {
197                                 wsi->lws_rx_parse_state = LWS_RXPS_NEW;
198                                 goto spill;
199                         }
200                 }
201                 break;
202
203         case LWS_RXPS_04_FRAME_HDR_LEN64_8:
204                 if (c & 0x80) {
205                         lwsl_warn("b63 of length must be zero\n");
206                         /* kill the connection */
207                         return -1;
208                 }
209 #if defined __LP64__
210                 wsi->u.ws.rx_packet_length = ((size_t)c) << 56;
211 #else
212                 wsi->u.ws.rx_packet_length = 0;
213 #endif
214                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7;
215                 break;
216
217         case LWS_RXPS_04_FRAME_HDR_LEN64_7:
218 #if defined __LP64__
219                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 48;
220 #endif
221                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
222                 break;
223
224         case LWS_RXPS_04_FRAME_HDR_LEN64_6:
225 #if defined __LP64__
226                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 40;
227 #endif
228                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
229                 break;
230
231         case LWS_RXPS_04_FRAME_HDR_LEN64_5:
232 #if defined __LP64__
233                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 32;
234 #endif
235                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
236                 break;
237
238         case LWS_RXPS_04_FRAME_HDR_LEN64_4:
239                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 24;
240                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3;
241                 break;
242
243         case LWS_RXPS_04_FRAME_HDR_LEN64_3:
244                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 16;
245                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2;
246                 break;
247
248         case LWS_RXPS_04_FRAME_HDR_LEN64_2:
249                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 8;
250                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1;
251                 break;
252
253         case LWS_RXPS_04_FRAME_HDR_LEN64_1:
254                 wsi->u.ws.rx_packet_length |= (size_t)c;
255                 if (wsi->u.ws.this_frame_masked)
256                         wsi->lws_rx_parse_state =
257                                         LWS_RXPS_07_COLLECT_FRAME_KEY_1;
258                 else {
259                         if (wsi->u.ws.rx_packet_length)
260                                 wsi->lws_rx_parse_state =
261                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
262                         else {
263                                 wsi->lws_rx_parse_state = LWS_RXPS_NEW;
264                                 goto spill;
265                         }
266                 }
267                 break;
268
269         case LWS_RXPS_07_COLLECT_FRAME_KEY_1:
270                 wsi->u.ws.mask[0] = c;
271                 if (c)
272                         wsi->u.ws.all_zero_nonce = 0;
273                 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2;
274                 break;
275
276         case LWS_RXPS_07_COLLECT_FRAME_KEY_2:
277                 wsi->u.ws.mask[1] = c;
278                 if (c)
279                         wsi->u.ws.all_zero_nonce = 0;
280                 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3;
281                 break;
282
283         case LWS_RXPS_07_COLLECT_FRAME_KEY_3:
284                 wsi->u.ws.mask[2] = c;
285                 if (c)
286                         wsi->u.ws.all_zero_nonce = 0;
287                 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4;
288                 break;
289
290         case LWS_RXPS_07_COLLECT_FRAME_KEY_4:
291                 wsi->u.ws.mask[3] = c;
292                 if (c)
293                         wsi->u.ws.all_zero_nonce = 0;
294
295                 if (wsi->u.ws.rx_packet_length)
296                         wsi->lws_rx_parse_state =
297                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
298                 else {
299                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
300                         goto spill;
301                 }
302                 break;
303
304         case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED:
305
306                 assert(wsi->u.ws.rx_ubuf);
307
308                 if (wsi->u.ws.rx_draining_ext)
309                         goto drain_extension;
310
311                 if (wsi->u.ws.this_frame_masked && !wsi->u.ws.all_zero_nonce)
312                         c ^= wsi->u.ws.mask[(wsi->u.ws.mask_idx++) & 3];
313
314                 wsi->u.ws.rx_ubuf[LWS_PRE + (wsi->u.ws.rx_ubuf_head++)] = c;
315
316                 if (--wsi->u.ws.rx_packet_length == 0) {
317                         /* spill because we have the whole frame */
318                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
319                         goto spill;
320                 }
321
322                 /*
323                  * if there's no protocol max frame size given, we are
324                  * supposed to default to context->pt_serv_buf_size
325                  */
326                 if (!wsi->protocol->rx_buffer_size &&
327                     wsi->u.ws.rx_ubuf_head != wsi->context->pt_serv_buf_size)
328                         break;
329
330                 if (wsi->protocol->rx_buffer_size &&
331                     wsi->u.ws.rx_ubuf_head != wsi->protocol->rx_buffer_size)
332                         break;
333
334                 /* spill because we filled our rx buffer */
335 spill:
336
337                 handled = 0;
338
339                 /*
340                  * is this frame a control packet we should take care of at this
341                  * layer?  If so service it and hide it from the user callback
342                  */
343
344                 switch (wsi->u.ws.opcode) {
345                 case LWSWSOPC_CLOSE:
346                         pp = (unsigned char *)&wsi->u.ws.rx_ubuf[LWS_PRE];
347                         if (lws_check_opt(wsi->context->options,
348                                           LWS_SERVER_OPTION_VALIDATE_UTF8) &&
349                             wsi->u.ws.rx_ubuf_head > 2 &&
350                             lws_check_utf8(&wsi->u.ws.utf8, pp + 2,
351                                            wsi->u.ws.rx_ubuf_head - 2))
352                                 goto utf8_fail;
353
354                         /* is this an acknowledgement of our close? */
355                         if (wsi->state == LWSS_AWAITING_CLOSE_ACK) {
356                                 /*
357                                  * fine he has told us he is closing too, let's
358                                  * finish our close
359                                  */
360                                 lwsl_parser("seen server's close ack\n");
361                                 return -1;
362                         }
363
364                         lwsl_parser("client sees server close len = %d\n",
365                                                  wsi->u.ws.rx_ubuf_head);
366                         if (wsi->u.ws.rx_ubuf_head >= 2) {
367                                 close_code = (pp[0] << 8) | pp[1];
368                                 if (close_code < 1000 ||
369                                     close_code == 1004 ||
370                                     close_code == 1005 ||
371                                     close_code == 1006 ||
372                                     close_code == 1012 ||
373                                     close_code == 1013 ||
374                                     close_code == 1014 ||
375                                     close_code == 1015 ||
376                                     (close_code >= 1016 && close_code < 3000)
377                                 ) {
378                                         pp[0] = (LWS_CLOSE_STATUS_PROTOCOL_ERR >> 8) & 0xff;
379                                         pp[1] = LWS_CLOSE_STATUS_PROTOCOL_ERR & 0xff;
380                                 }
381                         }
382                         if (user_callback_handle_rxflow(
383                                         wsi->protocol->callback, wsi,
384                                         LWS_CALLBACK_WS_PEER_INITIATED_CLOSE,
385                                         wsi->user_space, pp,
386                                         wsi->u.ws.rx_ubuf_head))
387                                 return -1;
388
389                         if (lws_partial_buffered(wsi))
390                                 /*
391                                  * if we're in the middle of something,
392                                  * we can't do a normal close response and
393                                  * have to just close our end.
394                                  */
395                                 wsi->socket_is_permanently_unusable = 1;
396                         else
397                                 /*
398                                  * parrot the close packet payload back
399                                  * we do not care about how it went, we are closing
400                                  * immediately afterwards
401                                  */
402                                 lws_write(wsi, (unsigned char *)&wsi->u.ws.rx_ubuf[LWS_PRE],
403                                           wsi->u.ws.rx_ubuf_head,
404                                           LWS_WRITE_CLOSE);
405                         wsi->state = LWSS_RETURNED_CLOSE_ALREADY;
406                         /* close the connection */
407                         return -1;
408
409                 case LWSWSOPC_PING:
410                         lwsl_info("received %d byte ping, sending pong\n",
411                                   wsi->u.ws.rx_ubuf_head);
412
413                         /* he set a close reason on this guy, ignore PING */
414                         if (wsi->u.ws.close_in_ping_buffer_len)
415                                 goto ping_drop;
416
417                         if (wsi->u.ws.ping_pending_flag) {
418                                 /*
419                                  * there is already a pending ping payload
420                                  * we should just log and drop
421                                  */
422                                 lwsl_parser("DROP PING since one pending\n");
423                                 goto ping_drop;
424                         }
425
426                         /* control packets can only be < 128 bytes long */
427                         if (wsi->u.ws.rx_ubuf_head > 128 - 3) {
428                                 lwsl_parser("DROP PING payload too large\n");
429                                 goto ping_drop;
430                         }
431
432                         /* stash the pong payload */
433                         memcpy(wsi->u.ws.ping_payload_buf + LWS_PRE,
434                                &wsi->u.ws.rx_ubuf[LWS_PRE],
435                                 wsi->u.ws.rx_ubuf_head);
436
437                         wsi->u.ws.ping_payload_len = wsi->u.ws.rx_ubuf_head;
438                         wsi->u.ws.ping_pending_flag = 1;
439
440                         /* get it sent as soon as possible */
441                         lws_callback_on_writable(wsi);
442 ping_drop:
443                         wsi->u.ws.rx_ubuf_head = 0;
444                         handled = 1;
445                         break;
446
447                 case LWSWSOPC_PONG:
448                         lwsl_info("client receied pong\n");
449                         lwsl_hexdump(&wsi->u.ws.rx_ubuf[LWS_PRE],
450                                      wsi->u.ws.rx_ubuf_head);
451
452                         if (wsi->pending_timeout == PENDING_TIMEOUT_WS_PONG_CHECK_GET_PONG) {
453                                 lwsl_info("received expected PONG on wsi %p\n", wsi);
454                                 lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
455                         }
456
457                         /* issue it */
458                         callback_action = LWS_CALLBACK_CLIENT_RECEIVE_PONG;
459                         break;
460
461                 case LWSWSOPC_CONTINUATION:
462                 case LWSWSOPC_TEXT_FRAME:
463                 case LWSWSOPC_BINARY_FRAME:
464                         break;
465
466                 default:
467
468                         lwsl_parser("Reserved opc 0x%2X\n", wsi->u.ws.opcode);
469
470                         /*
471                          * It's something special we can't understand here.
472                          * Pass the payload up to the extension's parsing
473                          * state machine.
474                          */
475
476                         eff_buf.token = &wsi->u.ws.rx_ubuf[LWS_PRE];
477                         eff_buf.token_len = wsi->u.ws.rx_ubuf_head;
478
479                         if (lws_ext_cb_active(wsi,
480                                 LWS_EXT_CB_EXTENDED_PAYLOAD_RX,
481                                         &eff_buf, 0) <= 0) { /* not handle or fail */
482
483                                 lwsl_ext("Unhandled ext opc 0x%x\n", wsi->u.ws.opcode);
484                                 wsi->u.ws.rx_ubuf_head = 0;
485
486                                 return 0;
487                         }
488                         handled = 1;
489                         break;
490                 }
491
492                 /*
493                  * No it's real payload, pass it up to the user callback.
494                  * It's nicely buffered with the pre-padding taken care of
495                  * so it can be sent straight out again using lws_write
496                  */
497                 if (handled)
498                         goto already_done;
499
500                 eff_buf.token = &wsi->u.ws.rx_ubuf[LWS_PRE];
501                 eff_buf.token_len = wsi->u.ws.rx_ubuf_head;
502
503 drain_extension:
504                 lwsl_ext("%s: passing %d to ext\n", __func__, eff_buf.token_len);
505
506                 n = lws_ext_cb_active(wsi, LWS_EXT_CB_PAYLOAD_RX, &eff_buf, 0);
507                 lwsl_ext("Ext RX returned %d\n", n);
508                 if (n < 0) {
509                         wsi->socket_is_permanently_unusable = 1;
510                         return -1;
511                 }
512
513                 lwsl_ext("post inflate eff_buf len %d\n", eff_buf.token_len);
514
515                 if (rx_draining_ext && !eff_buf.token_len) {
516                         lwsl_err("   --- ignoring zero drain result, ending drain\n");
517                         goto already_done;
518                 }
519
520                 if (wsi->u.ws.check_utf8 && !wsi->u.ws.defeat_check_utf8) {
521                         if (lws_check_utf8(&wsi->u.ws.utf8,
522                                            (unsigned char *)eff_buf.token,
523                                            eff_buf.token_len))
524                                 goto utf8_fail;
525
526                         /* we are ending partway through utf-8 character? */
527                         if (!wsi->u.ws.rx_packet_length && wsi->u.ws.final &&
528                             wsi->u.ws.utf8 && !n) {
529                                 lwsl_info("FINAL utf8 error\n");
530 utf8_fail:                      lwsl_info("utf8 error\n");
531                                 return -1;
532                         }
533                 }
534
535                 if (eff_buf.token_len < 0 &&
536                     callback_action != LWS_CALLBACK_CLIENT_RECEIVE_PONG)
537                         goto already_done;
538
539                 if (!eff_buf.token)
540                         goto already_done;
541
542                 eff_buf.token[eff_buf.token_len] = '\0';
543
544                 if (!wsi->protocol->callback)
545                         goto already_done;
546
547                 if (callback_action == LWS_CALLBACK_CLIENT_RECEIVE_PONG)
548                         lwsl_info("Client doing pong callback\n");
549
550                 if (n && eff_buf.token_len)
551                         /* extension had more... main loop will come back
552                          * we want callback to be done with this set, if so,
553                          * because lws_is_final() hides it was final until the
554                          * last chunk
555                          */
556                         lws_add_wsi_to_draining_ext_list(wsi);
557                 else
558                         lws_remove_wsi_from_draining_ext_list(wsi);
559
560                 if (wsi->state == LWSS_RETURNED_CLOSE_ALREADY ||
561                     wsi->state == LWSS_WAITING_TO_SEND_CLOSE_NOTIFICATION ||
562                     wsi->state == LWSS_AWAITING_CLOSE_ACK)
563                         goto already_done;
564
565                 m = wsi->protocol->callback(wsi,
566                         (enum lws_callback_reasons)callback_action,
567                         wsi->user_space, eff_buf.token, eff_buf.token_len);
568
569                 /* if user code wants to close, let caller know */
570                 if (m)
571                         return 1;
572
573 already_done:
574                 wsi->u.ws.rx_ubuf_head = 0;
575                 break;
576         default:
577                 lwsl_err("client rx illegal state\n");
578                 return 1;
579         }
580
581         return 0;
582
583 illegal_ctl_length:
584         lwsl_warn("Control frame asking for extended length is illegal\n");
585         /* kill the connection */
586         return -1;
587 }
588
589