fix null protocol dereference when closing session
[profile/ivi/libwebsockets.git] / lib / libwebsockets.c
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 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 #include <ifaddrs.h>
24
25 /*
26  * In-place str to lower case
27  */
28
29 static void
30 strtolower(char *s)
31 {
32         while (*s) {
33                 *s = tolower(*s);
34                 s++;
35         }
36 }
37
38 /* file descriptor hash management */
39
40 struct libwebsocket *
41 wsi_from_fd(struct libwebsocket_context *this, int fd)
42 {
43         int h = LWS_FD_HASH(fd);
44         int n = 0;
45
46         for (n = 0; n < this->fd_hashtable[h].length; n++)
47                 if (this->fd_hashtable[h].wsi[n]->sock == fd)
48                         return this->fd_hashtable[h].wsi[n];
49
50         return NULL;
51 }
52
53 int
54 insert_wsi(struct libwebsocket_context *this, struct libwebsocket *wsi)
55 {
56         int h = LWS_FD_HASH(wsi->sock);
57
58         if (this->fd_hashtable[h].length == MAX_CLIENTS - 1) {
59                 fprintf(stderr, "hash table overflow\n");
60                 return 1;
61         }
62
63         this->fd_hashtable[h].wsi[this->fd_hashtable[h].length++] = wsi;
64
65         return 0;
66 }
67
68 int
69 delete_from_fd(struct libwebsocket_context *this, int fd)
70 {
71         int h = LWS_FD_HASH(fd);
72         int n = 0;
73
74         for (n = 0; n < this->fd_hashtable[h].length; n++)
75                 if (this->fd_hashtable[h].wsi[n]->sock == fd) {
76                         while (n < this->fd_hashtable[h].length) {
77                                 this->fd_hashtable[h].wsi[n] =
78                                                this->fd_hashtable[h].wsi[n + 1];
79                                 n++;
80                         }
81                         this->fd_hashtable[h].length--;
82
83                         return 0;
84                 }
85
86         fprintf(stderr, "Failed to find fd %d requested for "
87                                                    "delete in hashtable\n", fd);
88         return 1;
89 }
90
91 #ifdef LWS_OPENSSL_SUPPORT
92 static void
93 libwebsockets_decode_ssl_error(void)
94 {
95         char buf[256];
96         u_long err;
97
98         while ((err = ERR_get_error()) != 0) {
99                 ERR_error_string_n(err, buf, sizeof(buf));
100                 fprintf(stderr, "*** %s\n", buf);
101         }
102 }
103 #endif
104
105
106 static int
107 interface_to_sa(const char* ifname, struct sockaddr_in *addr, size_t addrlen)
108 {
109         int rc = -1;
110         struct ifaddrs *ifr;
111         struct ifaddrs *ifc;
112         struct sockaddr_in *sin;
113
114         getifaddrs(&ifr);
115         for (ifc = ifr; ifc != NULL; ifc = ifc->ifa_next) {
116                 if (strcmp(ifc->ifa_name, ifname))
117                         continue;
118                 if (ifc->ifa_addr == NULL)
119                         continue;
120                 sin = (struct sockaddr_in *)ifc->ifa_addr;
121                 if (sin->sin_family != AF_INET)
122                         continue;
123                 memcpy(addr, sin, addrlen);
124                 rc = 0; 
125         }
126
127         freeifaddrs(ifr);
128
129         return rc;
130 }
131
132 void
133 libwebsocket_close_and_free_session(struct libwebsocket_context *this,
134                          struct libwebsocket *wsi, enum lws_close_status reason)
135 {
136         int n;
137         int old_state;
138         unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 +
139                                                   LWS_SEND_BUFFER_POST_PADDING];
140
141         if (!wsi)
142                 return;
143
144         old_state = wsi->state;
145
146         if (old_state == WSI_STATE_DEAD_SOCKET)
147                 return;
148
149         /* remove this fd from wsi mapping hashtable */
150
151         delete_from_fd(this, wsi->sock);
152
153         /* delete it from the internal poll list if still present */
154
155         for (n = 0; n < this->fds_count; n++) {
156                 if (this->fds[n].fd != wsi->sock)
157                         continue;
158                 while (n < this->fds_count - 1) {
159                         this->fds[n] = this->fds[n + 1];
160                         n++;
161                 }
162                 this->fds_count--;
163                 /* we only have to deal with one */
164                 n = this->fds_count;
165         }
166
167         /* remove also from external POLL support via protocol 0 */
168
169         this->protocols[0].callback(this, wsi,
170                     LWS_CALLBACK_DEL_POLL_FD, (void *)(long)wsi->sock, NULL, 0);
171
172         wsi->close_reason = reason;
173
174         /*
175          * signal we are closing, libsocket_write will
176          * add any necessary version-specific stuff.  If the write fails,
177          * no worries we are closing anyway.  If we didn't initiate this
178          * close, then our state has been changed to
179          * WSI_STATE_RETURNED_CLOSE_ALREADY and we will skip this
180          */
181
182         if (old_state == WSI_STATE_ESTABLISHED)
183                 libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 0,
184                                                                LWS_WRITE_CLOSE);
185
186         wsi->state = WSI_STATE_DEAD_SOCKET;
187
188         /* tell the user it's all over for this guy */
189
190         if (wsi->protocol && wsi->protocol->callback &&
191                                              old_state == WSI_STATE_ESTABLISHED)
192                 wsi->protocol->callback(this, wsi, LWS_CALLBACK_CLOSED,
193                                                       wsi->user_space, NULL, 0);
194
195         /* free up his allocations */
196
197         for (n = 0; n < WSI_TOKEN_COUNT; n++)
198                 if (wsi->utf8_token[n].token)
199                         free(wsi->utf8_token[n].token);
200
201 /*      fprintf(stderr, "closing fd=%d\n", wsi->sock); */
202
203 #ifdef LWS_OPENSSL_SUPPORT
204         if (wsi->ssl) {
205                 n = SSL_get_fd(wsi->ssl);
206                 SSL_shutdown(wsi->ssl);
207                 close(n);
208                 SSL_free(wsi->ssl);
209         } else {
210 #endif
211                 shutdown(wsi->sock, SHUT_RDWR);
212                 close(wsi->sock);
213 #ifdef LWS_OPENSSL_SUPPORT
214         }
215 #endif
216         if (wsi->user_space)
217                 free(wsi->user_space);
218
219         free(wsi);
220 }
221
222 /**
223  * libwebsockets_hangup_on_client() - Server calls to terminate client
224  *                                      connection
225  * @this:       libwebsockets context
226  * @fd:         Connection socket descriptor
227  */
228
229 void
230 libwebsockets_hangup_on_client(struct libwebsocket_context *this, int fd)
231 {
232         struct libwebsocket *wsi = wsi_from_fd(this, fd);
233
234         if (wsi == NULL)
235                 return;
236
237         libwebsocket_close_and_free_session(this, wsi,
238                                                      LWS_CLOSE_STATUS_NOSTATUS);
239 }
240
241
242 /**
243  * libwebsockets_get_peer_addresses() - Get client address information
244  * @fd:         Connection socket descriptor
245  * @name:       Buffer to take client address name
246  * @name_len:   Length of client address name buffer
247  * @rip:        Buffer to take client address IP qotted quad
248  * @rip_len:    Length of client address IP buffer
249  *
250  *      This function fills in @name and @rip with the name and IP of
251  *      the client connected with socket descriptor @fd.  Names may be
252  *      truncated if there is not enough room.  If either cannot be
253  *      determined, they will be returned as valid zero-length strings.
254  */
255
256 void
257 libwebsockets_get_peer_addresses(int fd, char *name, int name_len,
258                                         char *rip, int rip_len)
259 {
260         unsigned int len;
261         struct sockaddr_in sin;
262         struct hostent *host;
263         struct hostent *host1;
264         char ip[128];
265         char *p;
266         int n;
267
268         rip[0] = '\0';
269         name[0] = '\0';
270
271         len = sizeof sin;
272         if (getpeername(fd, (struct sockaddr *) &sin, &len) < 0) {
273                 perror("getpeername");
274                 return;
275         }
276                 
277         host = gethostbyaddr((char *) &sin.sin_addr, sizeof sin.sin_addr,
278                                                                        AF_INET);
279         if (host == NULL) {
280                 perror("gethostbyaddr");
281                 return;
282         }
283
284         strncpy(name, host->h_name, name_len);
285         name[name_len - 1] = '\0';
286
287         host1 = gethostbyname(host->h_name);
288         if (host1 == NULL)
289                 return;
290         p = (char *)host1;
291         n = 0;
292         while (p != NULL) {
293                 p = host1->h_addr_list[n++];
294                 if (p == NULL)
295                         continue;
296                 if (host1->h_addrtype != AF_INET)
297                         continue;
298
299                 sprintf(ip, "%d.%d.%d.%d",
300                                 p[0], p[1], p[2], p[3]);
301                 p = NULL;
302                 strncpy(rip, ip, rip_len);
303                 rip[rip_len - 1] = '\0';
304         }
305 }
306
307 /**
308  * libwebsocket_service_fd() - Service polled socket with something waiting
309  * @this:       Websocket context
310  * @pollfd:     The pollfd entry describing the socket fd and which events
311  *              happened.
312  *
313  *      This function closes any active connections and then frees the
314  *      context.  After calling this, any further use of the context is
315  *      undefined.
316  */
317
318 int
319 libwebsocket_service_fd(struct libwebsocket_context *this,
320                                                           struct pollfd *pollfd)
321 {
322         unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + MAX_BROADCAST_PAYLOAD +
323                                                   LWS_SEND_BUFFER_POST_PADDING];
324         struct libwebsocket *wsi;
325         struct libwebsocket *new_wsi;
326         int n;
327         int m;
328         size_t len;
329         int accept_fd;
330         unsigned int clilen;
331         struct sockaddr_in cli_addr;
332         struct timeval tv;
333         static const char magic_websocket_guid[] =
334                                          "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
335         static const char magic_websocket_04_masking_guid[] =
336                                          "61AC5F19-FBBA-4540-B96F-6561F1AB40A8";
337         char hash[20];
338         char pkt[1024];
339         char *p = &pkt[0];
340         const char *pc;
341         int okay = 0;
342 #ifdef LWS_OPENSSL_SUPPORT
343         char ssl_err_buf[512];
344 #endif
345         /*
346          * you can call us with pollfd = NULL to just allow the once-per-second
347          * global timeout checks; if less than a second since the last check
348          * it returns immediately then.
349          */
350
351         gettimeofday(&tv, NULL);
352
353         if (this->last_timeout_check_s != tv.tv_sec) {
354                 this->last_timeout_check_s = tv.tv_sec;
355
356                 /* global timeout check once per second */
357
358                 for (n = 0; n < this->fds_count; n++) {
359                         wsi = wsi_from_fd(this, this->fds[n].fd);
360                         if (!wsi->pending_timeout)
361                                 continue;
362
363                         /*
364                          * if we went beyond the allowed time, kill the
365                          * connection
366                          */
367
368                         if (tv.tv_sec > wsi->pending_timeout_limit)
369                                 libwebsocket_close_and_free_session(this, wsi,
370                                                      LWS_CLOSE_STATUS_NOSTATUS);
371                 }
372         }
373
374         /* just here for timeout management? */
375
376         if (pollfd == NULL)
377                 return 0;
378
379         /* no, here to service a socket descriptor */
380
381         wsi = wsi_from_fd(this, pollfd->fd);
382
383         if (wsi == NULL)
384                 return 1;
385
386         switch (wsi->mode) {
387         case LWS_CONNMODE_SERVER_LISTENER:
388
389                 /* pollin means a client has connected to us then */
390
391                 if (!pollfd->revents & POLLIN)
392                         break;
393
394                 /* listen socket got an unencrypted connection... */
395
396                 clilen = sizeof(cli_addr);
397                 accept_fd  = accept(pollfd->fd, (struct sockaddr *)&cli_addr,
398                                                                        &clilen);
399                 if (accept_fd < 0) {
400                         fprintf(stderr, "ERROR on accept");
401                         break;
402                 }
403
404                 if (this->fds_count >= MAX_CLIENTS) {
405                         fprintf(stderr, "too busy to accept new client\n");
406                         close(accept_fd);
407                         break;
408                 }
409
410                 /*
411                  * look at who we connected to and give user code a chance
412                  * to reject based on client IP.  There's no protocol selected
413                  * yet so we issue this to protocols[0]
414                  */
415
416                 if ((this->protocols[0].callback)(this, wsi,
417                                 LWS_CALLBACK_FILTER_NETWORK_CONNECTION,
418                                              (void*)(long)accept_fd, NULL, 0)) {
419                         fprintf(stderr, "Callback denied network connection\n");
420                         close(accept_fd);
421                         break;
422                 }
423
424                 /* accepting connection to main listener */
425
426                 new_wsi = malloc(sizeof(struct libwebsocket));
427                 if (new_wsi == NULL) {
428                         fprintf(stderr, "Out of memory for new connection\n");
429                         break;
430                 }
431
432                 memset(new_wsi, 0, sizeof (struct libwebsocket));
433                 new_wsi->sock = accept_fd;
434                 new_wsi->pending_timeout = NO_PENDING_TIMEOUT;
435
436 #ifdef LWS_OPENSSL_SUPPORT
437                 new_wsi->ssl = NULL;
438
439                 if (this->use_ssl) {
440
441                         new_wsi->ssl = SSL_new(this->ssl_ctx);
442                         if (new_wsi->ssl == NULL) {
443                                 fprintf(stderr, "SSL_new failed: %s\n",
444                                     ERR_error_string(SSL_get_error(
445                                     new_wsi->ssl, 0), NULL));
446                                     libwebsockets_decode_ssl_error();
447                                 free(new_wsi);
448                                 break;
449                         }
450
451                         SSL_set_fd(new_wsi->ssl, accept_fd);
452
453                         n = SSL_accept(new_wsi->ssl);
454                         if (n != 1) {
455                                 /*
456                                  * browsers seem to probe with various
457                                  * ssl params which fail then retry
458                                  * and succeed
459                                  */
460                                 debug("SSL_accept failed skt %u: %s\n",
461                                       pollfd->fd,
462                                       ERR_error_string(SSL_get_error(
463                                       new_wsi->ssl, n), NULL));
464                                 SSL_free(
465                                        new_wsi->ssl);
466                                 free(new_wsi);
467                                 break;
468                         }
469                         
470                         debug("accepted new SSL conn  "
471                               "port %u on fd=%d SSL ver %s\n",
472                                 ntohs(cli_addr.sin_port), accept_fd,
473                                   SSL_get_version(new_wsi->ssl));
474
475                 } else
476 #endif
477                         debug("accepted new conn  port %u on fd=%d\n",
478                                           ntohs(cli_addr.sin_port), accept_fd);
479
480                 /* intialize the instance struct */
481
482                 new_wsi->state = WSI_STATE_HTTP;
483                 new_wsi->name_buffer_pos = 0;
484                 new_wsi->mode = LWS_CONNMODE_WS_SERVING;
485
486                 for (n = 0; n < WSI_TOKEN_COUNT; n++) {
487                         new_wsi->utf8_token[n].token = NULL;
488                         new_wsi->utf8_token[n].token_len = 0;
489                 }
490
491                 /*
492                  * these can only be set once the protocol is known
493                  * we set an unestablished connection's protocol pointer
494                  * to the start of the supported list, so it can look
495                  * for matching ones during the handshake
496                  */
497                 new_wsi->protocol = this->protocols;
498                 new_wsi->user_space = NULL;
499
500                 /*
501                  * Default protocol is 76 / 00
502                  * After 76, there's a header specified to inform which
503                  * draft the client wants, when that's seen we modify
504                  * the individual connection's spec revision accordingly
505                  */
506                 new_wsi->ietf_spec_revision = 0;
507
508                 insert_wsi(this, new_wsi);
509
510                 /*
511                  * make sure NO events are seen yet on this new socket
512                  * (otherwise we inherit old fds[client].revents from
513                  * previous socket there and die mysteriously! )
514                  */
515                 this->fds[this->fds_count].revents = 0;
516
517                 this->fds[this->fds_count].events = POLLIN;
518                 this->fds[this->fds_count++].fd = accept_fd;
519
520                 /* external POLL support via protocol 0 */
521                 this->protocols[0].callback(this, new_wsi,
522                         LWS_CALLBACK_ADD_POLL_FD,
523                         (void *)(long)accept_fd, NULL, POLLIN);
524
525                 break;
526
527         case LWS_CONNMODE_BROADCAST_PROXY_LISTENER:
528
529                 /* as we are listening, POLLIN means accept() is needed */
530         
531                 if (!pollfd->revents & POLLIN)
532                         break;
533
534                 /* listen socket got an unencrypted connection... */
535
536                 clilen = sizeof(cli_addr);
537                 accept_fd  = accept(pollfd->fd, (struct sockaddr *)&cli_addr,
538                                                                        &clilen);
539                 if (accept_fd < 0) {
540                         fprintf(stderr, "ERROR on accept");
541                         break;
542                 }
543
544                 if (this->fds_count >= MAX_CLIENTS) {
545                         fprintf(stderr, "too busy to accept new broadcast "
546                                                               "proxy client\n");
547                         close(accept_fd);
548                         break;
549                 }
550
551                 /* create a dummy wsi for the connection and add it */
552
553                 new_wsi = malloc(sizeof(struct libwebsocket));
554                 memset(new_wsi, 0, sizeof (struct libwebsocket));
555                 new_wsi->sock = accept_fd;
556                 new_wsi->mode = LWS_CONNMODE_BROADCAST_PROXY;
557                 new_wsi->state = WSI_STATE_ESTABLISHED;
558                 /* note which protocol we are proxying */
559                 new_wsi->protocol_index_for_broadcast_proxy =
560                                         wsi->protocol_index_for_broadcast_proxy;
561                 insert_wsi(this, new_wsi);
562
563                 /* add connected socket to internal poll array */
564
565                 this->fds[this->fds_count].revents = 0;
566                 this->fds[this->fds_count].events = POLLIN;
567                 this->fds[this->fds_count++].fd = accept_fd;
568
569                 /* external POLL support via protocol 0 */
570                 this->protocols[0].callback(this, new_wsi,
571                         LWS_CALLBACK_ADD_POLL_FD,
572                         (void *)(long)accept_fd, NULL, POLLIN);
573
574                 break;
575
576         case LWS_CONNMODE_BROADCAST_PROXY:
577
578                 /* handle session socket closed */
579
580                 if (pollfd->revents & (POLLERR | POLLHUP)) {
581
582                         debug("Session Socket %p (fd=%d) dead\n",
583                                 (void *)wsi, pollfd->fd);
584
585                         libwebsocket_close_and_free_session(this, wsi,
586                                                        LWS_CLOSE_STATUS_NORMAL);
587                         return 1;
588                 }
589
590                 /* the guy requested a callback when it was OK to write */
591
592                 if (pollfd->revents & POLLOUT) {
593
594                         /* one shot */
595
596                         pollfd->events &= ~POLLOUT;
597
598                         /* external POLL support via protocol 0 */
599                         this->protocols[0].callback(this, wsi,
600                                 LWS_CALLBACK_CLEAR_MODE_POLL_FD,
601                                 (void *)(long)wsi->sock, NULL, POLLOUT);
602
603                         wsi->protocol->callback(this, wsi,
604                                 LWS_CALLBACK_CLIENT_WRITEABLE,
605                                 wsi->user_space,
606                                 NULL, 0);
607                 }
608
609                 /* any incoming data ready? */
610
611                 if (!(pollfd->revents & POLLIN))
612                         break;
613
614                 /* get the issued broadcast payload from the socket */
615
616                 len = read(pollfd->fd, buf + LWS_SEND_BUFFER_PRE_PADDING,
617                                                          MAX_BROADCAST_PAYLOAD);
618                 if (len < 0) {
619                         fprintf(stderr, "Error reading broadcast payload\n");
620                         break;
621                 }
622
623                 /* broadcast it to all guys with this protocol index */
624
625                 for (n = 0; n < FD_HASHTABLE_MODULUS; n++) {
626
627                         for (m = 0; m < this->fd_hashtable[n].length; m++) {
628
629                                 new_wsi = this->fd_hashtable[n].wsi[m];
630
631                                 /* only to clients we are serving to */
632
633                                 if (new_wsi->mode != LWS_CONNMODE_WS_SERVING)
634                                         continue;
635
636                                 /*
637                                  * never broadcast to non-established
638                                  * connection
639                                  */
640
641                                 if (new_wsi->state != WSI_STATE_ESTABLISHED)
642                                         continue;
643
644                                 /*
645                                  * only broadcast to connections using
646                                  * the requested protocol
647                                  */
648
649                                 if (new_wsi->protocol->protocol_index !=
650                                         wsi->protocol_index_for_broadcast_proxy)
651                                         continue;
652
653                                 /* broadcast it to this connection */
654
655                                 new_wsi->protocol->callback(this, new_wsi,
656                                         LWS_CALLBACK_BROADCAST,
657                                         new_wsi->user_space,
658                                         buf + LWS_SEND_BUFFER_PRE_PADDING, len);
659                         }
660                 }
661                 break;
662
663         case LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY:
664
665                 /* handle proxy hung up on us */
666
667                 if (pollfd->revents & (POLLERR | POLLHUP)) {
668
669                         fprintf(stderr, "Proxy connection %p (fd=%d) dead\n",
670                                 (void *)wsi, pollfd->fd);
671
672                         libwebsocket_close_and_free_session(this, wsi,
673                                                      LWS_CLOSE_STATUS_NOSTATUS);
674                         return 1;
675                 }
676
677                 n = recv(wsi->sock, pkt, sizeof pkt, 0);
678                 if (n < 0) {
679                         libwebsocket_close_and_free_session(this, wsi,
680                                                      LWS_CLOSE_STATUS_NOSTATUS);
681                         fprintf(stderr, "ERROR reading from proxy socket\n");
682                         return 1;
683                 }
684
685                 pkt[13] = '\0';
686                 if (strcmp(pkt, "HTTP/1.0 200 ") != 0) {
687                         libwebsocket_close_and_free_session(this, wsi,
688                                                      LWS_CLOSE_STATUS_NOSTATUS);
689                         fprintf(stderr, "ERROR from proxy: %s\n", pkt);
690                         return 1;
691                 }
692
693                 /* clear his proxy connection timeout */
694
695                 libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
696
697                 /* fallthru */
698
699         case LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE:
700
701         #ifdef LWS_OPENSSL_SUPPORT
702                 if (wsi->use_ssl) {
703
704                         wsi->ssl = SSL_new(this->ssl_client_ctx);
705                         wsi->client_bio = BIO_new_socket(wsi->sock, BIO_NOCLOSE);
706                         SSL_set_bio(wsi->ssl, wsi->client_bio, wsi->client_bio);
707
708                         SSL_set_ex_data(wsi->ssl,
709                               this->openssl_websocket_private_data_index, this);
710
711                         if (SSL_connect(wsi->ssl) <= 0) {
712                                 fprintf(stderr, "SSL connect error %s\n",
713                                         ERR_error_string(ERR_get_error(),
714                                                                   ssl_err_buf));
715                                 libwebsocket_close_and_free_session(this, wsi,
716                                                      LWS_CLOSE_STATUS_NOSTATUS);
717                                 return 1;
718                         }
719
720                         n = SSL_get_verify_result(wsi->ssl);
721                         if (n != X509_V_OK) && (
722                                 n != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
723                                                            wsi->use_ssl != 2)) {
724
725                                 fprintf(stderr, "server's cert didn't "
726                                                            "look good %d\n", n);
727                                 libwebsocket_close_and_free_session(this, wsi,
728                                                      LWS_CLOSE_STATUS_NOSTATUS);
729                                 return 1;
730                         }
731                 } else {
732                         wsi->ssl = NULL;
733         #endif
734
735
736         #ifdef LWS_OPENSSL_SUPPORT
737                 }
738         #endif
739
740                 /*
741                  * create the random key
742                  */
743
744                 n = read(this->fd_random, hash, 16);
745                 if (n != 16) {
746                         fprintf(stderr, "Unable to read from random dev %s\n",
747                                                         SYSTEM_RANDOM_FILEPATH);
748                         free(wsi->c_path);
749                         free(wsi->c_host);
750                         if (wsi->c_origin)
751                                 free(wsi->c_origin);
752                         if (wsi->c_protocol)
753                                 free(wsi->c_protocol);
754                         libwebsocket_close_and_free_session(this, wsi,
755                                                      LWS_CLOSE_STATUS_NOSTATUS);
756                         return 1;
757                 }
758
759                 lws_b64_encode_string(hash, 16, wsi->key_b64,
760                                                            sizeof wsi->key_b64);
761
762                 /*
763                  * 04 example client handshake
764                  *
765                  * GET /chat HTTP/1.1
766                  * Host: server.example.com
767                  * Upgrade: websocket
768                  * Connection: Upgrade
769                  * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
770                  * Sec-WebSocket-Origin: http://example.com
771                  * Sec-WebSocket-Protocol: chat, superchat
772                  * Sec-WebSocket-Version: 4
773                  */
774
775                 p += sprintf(p, "GET %s HTTP/1.1\x0d\x0a", wsi->c_path);
776                 p += sprintf(p, "Host: %s\x0d\x0a", wsi->c_host);
777                 p += sprintf(p, "Upgrade: websocket\x0d\x0a");
778                 p += sprintf(p, "Connection: Upgrade\x0d\x0a"
779                                         "Sec-WebSocket-Key: ");
780                 strcpy(p, wsi->key_b64);
781                 p += strlen(wsi->key_b64);
782                 p += sprintf(p, "\x0d\x0a");
783                 if (wsi->c_origin)
784                         p += sprintf(p, "Sec-WebSocket-Origin: %s\x0d\x0a",
785                                                                  wsi->c_origin);
786                 if (wsi->c_protocol)
787                         p += sprintf(p, "Sec-WebSocket-Protocol: %s\x0d\x0a",
788                                                                wsi->c_protocol);
789                 p += sprintf(p, "Sec-WebSocket-Version: %d\x0d\x0a\x0d\x0a",
790                                                        wsi->ietf_spec_revision);
791
792                 /* done with these now */
793
794                 free(wsi->c_path);
795                 free(wsi->c_host);
796                 if (wsi->c_origin)
797                         free(wsi->c_origin);
798
799                 /* prepare the expected server accept response */
800
801                 strcpy((char *)buf, wsi->key_b64);
802                 strcpy((char *)&buf[strlen((char *)buf)], magic_websocket_guid);
803
804                 SHA1(buf, strlen((char *)buf), (unsigned char *)hash);
805
806                 lws_b64_encode_string(hash, 20,
807                                 wsi->initial_handshake_hash_base64,
808                                      sizeof wsi->initial_handshake_hash_base64);
809
810                 /* send our request to the server */
811
812         #ifdef LWS_OPENSSL_SUPPORT
813                 if (wsi->use_ssl)
814                         n = SSL_write(wsi->ssl, pkt, p - pkt);
815                 else
816         #endif
817                         n = send(wsi->sock, pkt, p - pkt, 0);
818
819                 if (n < 0) {
820                         fprintf(stderr, "ERROR writing to client socket\n");
821                         libwebsocket_close_and_free_session(this, wsi,
822                                                      LWS_CLOSE_STATUS_NOSTATUS);
823                         return 1;
824                 }
825
826                 wsi->parser_state = WSI_TOKEN_NAME_PART;
827                 wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY;
828                 libwebsocket_set_timeout(wsi,
829                                 PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE, 5);
830
831                 break;
832
833         case LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY:
834
835                 /* handle server hung up on us */
836
837                 if (pollfd->revents & (POLLERR | POLLHUP)) {
838
839                         fprintf(stderr, "Server connection %p (fd=%d) dead\n",
840                                 (void *)wsi, pollfd->fd);
841
842                         goto bail3;
843                 }
844
845
846                 /* interpret the server response */
847
848                 /*
849                  *  HTTP/1.1 101 Switching Protocols
850                  *  Upgrade: websocket
851                  *  Connection: Upgrade
852                  *  Sec-WebSocket-Accept: me89jWimTRKTWwrS3aRrL53YZSo=
853                  *  Sec-WebSocket-Nonce: AQIDBAUGBwgJCgsMDQ4PEC==
854                  *  Sec-WebSocket-Protocol: chat
855                  */
856
857         #ifdef LWS_OPENSSL_SUPPORT
858                 if (wsi->use_ssl)
859                         len = SSL_read(wsi->ssl, pkt, sizeof pkt);
860                 else
861         #endif
862                         len = recv(wsi->sock, pkt, sizeof pkt, 0);
863
864                 if (len < 0) {
865                         fprintf(stderr,
866                                   "libwebsocket_client_handshake read error\n");
867                         goto bail3;
868                 }
869
870                 p = pkt;
871                 for (n = 0; n < len; n++)
872                         libwebsocket_parse(wsi, *p++);
873
874                 if (wsi->parser_state != WSI_PARSING_COMPLETE) {
875                         fprintf(stderr, "libwebsocket_client_handshake "
876                                         "server response ailed parsing\n");
877                         goto bail3;
878                 }
879
880                 /*
881                  * well, what the server sent looked reasonable for syntax.
882                  * Now let's confirm it sent all the necessary headers
883                  */
884
885                  if (!wsi->utf8_token[WSI_TOKEN_HTTP].token_len ||
886                         !wsi->utf8_token[WSI_TOKEN_UPGRADE].token_len ||
887                         !wsi->utf8_token[WSI_TOKEN_CONNECTION].token_len ||
888                         !wsi->utf8_token[WSI_TOKEN_ACCEPT].token_len ||
889                         (!wsi->utf8_token[WSI_TOKEN_NONCE].token_len &&
890                                            wsi->ietf_spec_revision == 4) ||
891                         (!wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len &&
892                                                      wsi->c_protocol != NULL)) {
893                         fprintf(stderr, "libwebsocket_client_handshake "
894                                                 "missing required header(s)\n");
895                         pkt[len] = '\0';
896                         fprintf(stderr, "%s", pkt);
897                         goto bail3;
898                 }
899
900                 /*
901                  * Everything seems to be there, now take a closer look at what
902                  * is in each header
903                  */
904
905                 strtolower(wsi->utf8_token[WSI_TOKEN_HTTP].token);
906                 if (strcmp(wsi->utf8_token[WSI_TOKEN_HTTP].token,
907                                                    "101 switching protocols")) {
908                         fprintf(stderr, "libwebsocket_client_handshake "
909                                         "server sent bad HTTP response '%s'\n",
910                                          wsi->utf8_token[WSI_TOKEN_HTTP].token);
911                         goto bail3;
912                 }
913
914                 strtolower(wsi->utf8_token[WSI_TOKEN_UPGRADE].token);
915                 if (strcmp(wsi->utf8_token[WSI_TOKEN_UPGRADE].token,
916                                                                  "websocket")) {
917                         fprintf(stderr, "libwebsocket_client_handshake server "
918                                         "sent bad Upgrade header '%s'\n",
919                                       wsi->utf8_token[WSI_TOKEN_UPGRADE].token);
920                         goto bail3;
921                 }
922
923                 strtolower(wsi->utf8_token[WSI_TOKEN_CONNECTION].token);
924                 if (strcmp(wsi->utf8_token[WSI_TOKEN_CONNECTION].token,
925                                                                    "upgrade")) {
926                         fprintf(stderr, "libwebsocket_client_handshake server "
927                                         "sent bad Connection hdr '%s'\n",
928                                    wsi->utf8_token[WSI_TOKEN_CONNECTION].token);
929                         goto bail3;
930                 }
931
932
933                 pc = wsi->c_protocol;
934
935                 /*
936                  * confirm the protocol the server wants to talk was in the list
937                  * of protocols we offered
938                  */
939
940                 if (!wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len) {
941
942                         /*
943                          * no protocol name to work from,
944                          * default to first protocol
945                          */
946                         wsi->protocol = &this->protocols[0];
947
948                         free(wsi->c_protocol);
949
950                         goto check_accept;
951                 }
952
953                 while (*pc && !okay) {
954                         if ((!strncmp(pc,
955                                 wsi->utf8_token[WSI_TOKEN_PROTOCOL].token,
956                            wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len)) &&
957                  (pc[wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len] == ',' ||
958                    pc[wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len] == '\0')) {
959                                 okay = 1;
960                                 continue;
961                         }
962                         while (*pc && *pc != ',')
963                                 pc++;
964                         while (*pc && *pc != ' ')
965                                 pc++;
966                 }
967
968                 /* done with him now */
969
970                 if (wsi->c_protocol)
971                         free(wsi->c_protocol);
972
973
974                 if (!okay) {
975                         fprintf(stderr, "libwebsocket_client_handshake server "
976                                                 "sent bad protocol '%s'\n",
977                                      wsi->utf8_token[WSI_TOKEN_PROTOCOL].token);
978                         goto bail2;
979                 }
980
981                 /*
982                  * identify the selected protocol struct and set it
983                  */
984                 n = 0;
985                 wsi->protocol = NULL;
986                 while (this->protocols[n].callback) {
987                         if (strcmp(wsi->utf8_token[WSI_TOKEN_PROTOCOL].token,
988                                                this->protocols[n].name) == 0)
989                                 wsi->protocol = &this->protocols[n];
990                         n++;
991                 }
992
993                 if (wsi->protocol == NULL) {
994                         fprintf(stderr, "libwebsocket_client_handshake server "
995                                         "requested protocol '%s', which we "
996                                         "said we supported but we don't!\n",
997                                      wsi->utf8_token[WSI_TOKEN_PROTOCOL].token);
998                         goto bail2;
999                 }
1000
1001         check_accept:
1002                 /*
1003                  * Confirm his accept token is the one we precomputed
1004                  */
1005
1006                 if (strcmp(wsi->utf8_token[WSI_TOKEN_ACCEPT].token,
1007                                           wsi->initial_handshake_hash_base64)) {
1008                         fprintf(stderr, "libwebsocket_client_handshake server "
1009                                 "sent bad ACCEPT '%s' vs computed '%s'\n",
1010                                 wsi->utf8_token[WSI_TOKEN_ACCEPT].token,
1011                                             wsi->initial_handshake_hash_base64);
1012                         goto bail2;
1013                 }
1014
1015                 if (wsi->ietf_spec_revision == 4) {
1016                         /*
1017                          * Calculate the 04 masking key to use when
1018                          * sending data to server
1019                          */
1020
1021                         strcpy((char *)buf, wsi->key_b64);
1022                         p = (char *)buf + strlen(wsi->key_b64);
1023                         strcpy(p, wsi->utf8_token[WSI_TOKEN_NONCE].token);
1024                         p += wsi->utf8_token[WSI_TOKEN_NONCE].token_len;
1025                         strcpy(p, magic_websocket_04_masking_guid);
1026                         SHA1(buf, strlen((char *)buf), wsi->masking_key_04);
1027                 }
1028
1029                 /* allocate the per-connection user memory (if any) */
1030
1031                 if (wsi->protocol->per_session_data_size) {
1032                         wsi->user_space = malloc(
1033                                           wsi->protocol->per_session_data_size);
1034                         if (wsi->user_space  == NULL) {
1035                                 fprintf(stderr, "Out of memory for "
1036                                                            "conn user space\n");
1037                                 goto bail2;
1038                         }
1039                 } else
1040                         wsi->user_space = NULL;
1041
1042                 /* clear his proxy connection timeout */
1043
1044                 libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
1045
1046                 /* mark him as being alive */
1047
1048                 wsi->state = WSI_STATE_ESTABLISHED;
1049                 wsi->mode = LWS_CONNMODE_WS_CLIENT;
1050
1051                 fprintf(stderr, "handshake OK for protocol %s\n",
1052                                                            wsi->protocol->name);
1053
1054                 /* call him back to inform him he is up */
1055
1056                 wsi->protocol->callback(this, wsi,
1057                                  LWS_CALLBACK_CLIENT_ESTABLISHED,
1058                                  wsi->user_space,
1059                                  NULL, 0);
1060
1061                 break;
1062
1063 bail3:
1064                 if (wsi->c_protocol)
1065                         free(wsi->c_protocol);
1066
1067 bail2:
1068                 libwebsocket_close_and_free_session(this, wsi,
1069                                                      LWS_CLOSE_STATUS_NOSTATUS);
1070                 return 1;
1071                 
1072
1073         case LWS_CONNMODE_WS_SERVING:
1074         case LWS_CONNMODE_WS_CLIENT:
1075
1076                 /* handle session socket closed */
1077
1078                 if (pollfd->revents & (POLLERR | POLLHUP)) {
1079
1080                         fprintf(stderr, "Session Socket %p (fd=%d) dead\n",
1081                                 (void *)wsi, pollfd->fd);
1082
1083                         libwebsocket_close_and_free_session(this, wsi,
1084                                                      LWS_CLOSE_STATUS_NOSTATUS);
1085                         return 1;
1086                 }
1087
1088                 /* the guy requested a callback when it was OK to write */
1089
1090                 if (pollfd->revents & POLLOUT) {
1091
1092                         pollfd->events &= ~POLLOUT;
1093
1094                         /* external POLL support via protocol 0 */
1095                         this->protocols[0].callback(this, wsi,
1096                                 LWS_CALLBACK_CLEAR_MODE_POLL_FD,
1097                                 (void *)(long)wsi->sock, NULL, POLLOUT);
1098
1099                         wsi->protocol->callback(this, wsi,
1100                                 LWS_CALLBACK_CLIENT_WRITEABLE,
1101                                 wsi->user_space,
1102                                 NULL, 0);
1103                 }
1104
1105                 /* any incoming data ready? */
1106
1107                 if (!(pollfd->revents & POLLIN))
1108                         break;
1109
1110 #ifdef LWS_OPENSSL_SUPPORT
1111                 if (wsi->ssl)
1112                         n = SSL_read(wsi->ssl, buf, sizeof buf);
1113                 else
1114 #endif
1115                         n = recv(pollfd->fd, buf, sizeof buf, 0);
1116
1117                 if (n < 0) {
1118                         fprintf(stderr, "Socket read returned %d\n", n);
1119                         break;
1120                 }
1121                 if (!n) {
1122                         libwebsocket_close_and_free_session(this, wsi,
1123                                                      LWS_CLOSE_STATUS_NOSTATUS);
1124                         return 1;
1125                 }
1126
1127                 /* service incoming data */
1128
1129                 n = libwebsocket_read(this, wsi, buf, n);
1130                 if (n >= 0)
1131                         break;
1132
1133                 /* we closed wsi */
1134
1135                 return 1;
1136         }
1137
1138         return 0;
1139 }
1140
1141
1142 /**
1143  * libwebsocket_context_destroy() - Destroy the websocket context
1144  * @this:       Websocket context
1145  *
1146  *      This function closes any active connections and then frees the
1147  *      context.  After calling this, any further use of the context is
1148  *      undefined.
1149  */
1150 void
1151 libwebsocket_context_destroy(struct libwebsocket_context *this)
1152 {
1153         int n;
1154         int m;
1155         struct libwebsocket *wsi;
1156
1157         for (n = 0; n < FD_HASHTABLE_MODULUS; n++)
1158                 for (m = 0; m < this->fd_hashtable[n].length; m++) {
1159                         wsi = this->fd_hashtable[n].wsi[m];
1160                         libwebsocket_close_and_free_session(this, wsi,
1161                                                     LWS_CLOSE_STATUS_GOINGAWAY);
1162                 }
1163
1164         close(this->fd_random);
1165
1166 #ifdef LWS_OPENSSL_SUPPORT
1167         if (this->ssl_ctx)
1168                 SSL_CTX_free(this->ssl_ctx);
1169         if (this->ssl_client_ctx)
1170                 SSL_CTX_free(this->ssl_client_ctx);
1171 #endif
1172
1173         free(this);
1174 }
1175
1176 /**
1177  * libwebsocket_service() - Service any pending websocket activity
1178  * @this:       Websocket context
1179  * @timeout_ms: Timeout for poll; 0 means return immediately if nothing needed
1180  *              service otherwise block and service immediately, returning
1181  *              after the timeout if nothing needed service.
1182  *
1183  *      This function deals with any pending websocket traffic, for three
1184  *      kinds of event.  It handles these events on both server and client
1185  *      types of connection the same.
1186  *
1187  *      1) Accept new connections to our context's server
1188  *
1189  *      2) Perform pending broadcast writes initiated from other forked
1190  *         processes (effectively serializing asynchronous broadcasts)
1191  *
1192  *      3) Call the receive callback for incoming frame data received by
1193  *          server or client connections.
1194  *
1195  *      You need to call this service function periodically to all the above
1196  *      functions to happen; if your application is single-threaded you can
1197  *      just call it in your main event loop.
1198  *
1199  *      Alternatively you can fork a new process that asynchronously handles
1200  *      calling this service in a loop.  In that case you are happy if this
1201  *      call blocks your thread until it needs to take care of something and
1202  *      would call it with a large nonzero timeout.  Your loop then takes no
1203  *      CPU while there is nothing happening.
1204  *
1205  *      If you are calling it in a single-threaded app, you don't want it to
1206  *      wait around blocking other things in your loop from happening, so you
1207  *      would call it with a timeout_ms of 0, so it returns immediately if
1208  *      nothing is pending, or as soon as it services whatever was pending.
1209  */
1210
1211
1212 int
1213 libwebsocket_service(struct libwebsocket_context *this, int timeout_ms)
1214 {
1215         int n;
1216
1217         /* stay dead once we are dead */
1218
1219         if (this == NULL)
1220                 return 1;
1221
1222         /* wait for something to need service */
1223
1224         n = poll(this->fds, this->fds_count, timeout_ms);
1225         if (n == 0) /* poll timeout */
1226                 return 0;
1227
1228         if (n < 0) {
1229                 /*
1230                 fprintf(stderr, "Listen Socket dead\n");
1231                 */
1232                 return 1;
1233         }
1234
1235         /* handle accept on listening socket? */
1236
1237         for (n = 0; n < this->fds_count; n++)
1238                 if (this->fds[n].revents)
1239                         libwebsocket_service_fd(this, &this->fds[n]);
1240
1241         return 0;
1242 }
1243
1244 /**
1245  * libwebsocket_callback_on_writable() - Request a callback when this socket
1246  *                                       becomes able to be written to without
1247  *                                       blocking
1248  *
1249  * @this:       libwebsockets context
1250  * @wsi:        Websocket connection instance to get callback for
1251  */
1252
1253 int
1254 libwebsocket_callback_on_writable(struct libwebsocket_context *this,
1255                                                        struct libwebsocket *wsi)
1256 {
1257         int n;
1258
1259         for (n = 0; n < this->fds_count; n++)
1260                 if (this->fds[n].fd == wsi->sock) {
1261                         this->fds[n].events |= POLLOUT;
1262                         n = this->fds_count;
1263                 }
1264
1265         /* external POLL support via protocol 0 */
1266         this->protocols[0].callback(this, wsi,
1267                 LWS_CALLBACK_SET_MODE_POLL_FD,
1268                 (void *)(long)wsi->sock, NULL, POLLOUT);
1269
1270         return 1;
1271 }
1272
1273 /**
1274  * libwebsocket_callback_on_writable_all_protocol() - Request a callback for
1275  *                      all connections using the given protocol when it
1276  *                      becomes possible to write to each socket without
1277  *                      blocking in turn.
1278  *
1279  * @protocol:   Protocol whose connections will get callbacks
1280  */
1281
1282 int
1283 libwebsocket_callback_on_writable_all_protocol(
1284                                   const struct libwebsocket_protocols *protocol)
1285 {
1286         struct libwebsocket_context *this = protocol->owning_server;
1287         int n;
1288         int m;
1289         struct libwebsocket *wsi;
1290
1291         for (n = 0; n < FD_HASHTABLE_MODULUS; n++) {
1292
1293                 for (m = 0; m < this->fd_hashtable[n].length; m++) {
1294
1295                         wsi = this->fd_hashtable[n].wsi[m];
1296
1297                         if (wsi->protocol == protocol)
1298                                 libwebsocket_callback_on_writable(this, wsi);
1299                 }
1300         }
1301
1302         return 0;
1303 }
1304
1305 /**
1306  * libwebsocket_set_timeout() - marks the wsi as subject to a timeout
1307  *
1308  * You will not need this unless you are doing something special
1309  *
1310  * @wsi:        Websocket connection instance
1311  * @reason:     timeout reason
1312  * @secs:       how many seconds
1313  */
1314
1315 void
1316 libwebsocket_set_timeout(struct libwebsocket *wsi,
1317                                           enum pending_timeout reason, int secs)
1318 {
1319         struct timeval tv;
1320
1321         gettimeofday(&tv, NULL);
1322
1323         wsi->pending_timeout_limit = tv.tv_sec + secs;
1324         wsi->pending_timeout = reason;
1325 }
1326
1327
1328 /**
1329  * libwebsocket_get_socket_fd() - returns the socket file descriptor
1330  *
1331  * You will not need this unless you are doing something special
1332  *
1333  * @wsi:        Websocket connection instance
1334  */
1335
1336 int
1337 libwebsocket_get_socket_fd(struct libwebsocket *wsi)
1338 {
1339         return wsi->sock;
1340 }
1341
1342 /**
1343  * libwebsocket_rx_flow_control() - Enable and disable socket servicing for
1344  *                              receieved packets.
1345  *
1346  * If the output side of a server process becomes choked, this allows flow
1347  * control for the input side.
1348  *
1349  * @wsi:        Websocket connection instance to get callback for
1350  * @enable:     0 = disable read servicing for this connection, 1 = enable
1351  */
1352
1353 int
1354 libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable)
1355 {
1356         struct libwebsocket_context *this = wsi->protocol->owning_server;
1357         int n;
1358
1359         for (n = 0; n < this->fds_count; n++)
1360                 if (this->fds[n].fd == wsi->sock) {
1361                         if (enable)
1362                                 this->fds[n].events |= POLLIN;
1363                         else
1364                                 this->fds[n].events &= ~POLLIN;
1365
1366                         return 0;
1367                 }
1368
1369         if (enable)
1370                 /* external POLL support via protocol 0 */
1371                 this->protocols[0].callback(this, wsi,
1372                         LWS_CALLBACK_SET_MODE_POLL_FD,
1373                         (void *)(long)wsi->sock, NULL, POLLIN);
1374         else
1375                 /* external POLL support via protocol 0 */
1376                 this->protocols[0].callback(this, wsi,
1377                         LWS_CALLBACK_CLEAR_MODE_POLL_FD,
1378                         (void *)(long)wsi->sock, NULL, POLLIN);
1379
1380
1381         fprintf(stderr, "libwebsocket_callback_on_writable "
1382                                                      "unable to find socket\n");
1383         return 1;
1384 }
1385
1386 /**
1387  * libwebsocket_canonical_hostname() - returns this host's hostname
1388  *
1389  * This is typically used by client code to fill in the host parameter
1390  * when making a client connection.  You can only call it after the context
1391  * has been created.
1392  *
1393  * @this:       Websocket context
1394  */
1395
1396
1397 extern const char *
1398 libwebsocket_canonical_hostname(struct libwebsocket_context *this)
1399 {
1400         return (const char *)this->canonical_hostname;
1401 }
1402
1403
1404 static void sigpipe_handler(int x)
1405 {
1406 }
1407
1408 #ifdef LWS_OPENSSL_SUPPORT
1409 static int
1410 OpenSSL_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
1411 {
1412
1413         SSL *ssl;
1414         int n;
1415 //      struct libwebsocket_context *this;
1416
1417         ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
1418                 SSL_get_ex_data_X509_STORE_CTX_idx());
1419
1420         /*
1421          * !!! can't get this->openssl_websocket_private_data_index
1422          * can't store as a static either
1423          */
1424 //      this = SSL_get_ex_data(ssl, this->openssl_websocket_private_data_index);
1425         
1426         n = this->protocols[0].callback(NULL, NULL,
1427                 LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION,
1428                                                    x509_ctx, ssl, preverify_ok);
1429
1430         /* convert return code from 0 = OK to 1 = OK */
1431
1432         if (!n)
1433                 n = 1;
1434         else
1435                 n = 0;
1436
1437         return n;
1438 }
1439 #endif
1440
1441
1442 /**
1443  * libwebsocket_create_context() - Create the websocket handler
1444  * @port:       Port to listen on... you can use 0 to suppress listening on
1445  *              any port, that's what you want if you are not running a
1446  *              websocket server at all but just using it as a client
1447  * @interface:  NULL to bind the listen socket to all interfaces, or the
1448  *              interface name, eg, "eth2"
1449  * @protocols:  Array of structures listing supported protocols and a protocol-
1450  *              specific callback for each one.  The list is ended with an
1451  *              entry that has a NULL callback pointer.
1452  *              It's not const because we write the owning_server member
1453  * @ssl_cert_filepath:  If libwebsockets was compiled to use ssl, and you want
1454  *                      to listen using SSL, set to the filepath to fetch the
1455  *                      server cert from, otherwise NULL for unencrypted
1456  * @ssl_private_key_filepath: filepath to private key if wanting SSL mode,
1457  *                      else ignored
1458  * @gid:        group id to change to after setting listen socket, or -1.
1459  * @uid:        user id to change to after setting listen socket, or -1.
1460  * @options:    0, or LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK
1461  *
1462  *      This function creates the listening socket and takes care
1463  *      of all initialization in one step.
1464  *
1465  *      After initialization, it returns a struct libwebsocket_context * that
1466  *      represents this server.  After calling, user code needs to take care
1467  *      of calling libwebsocket_service() with the context pointer to get the
1468  *      server's sockets serviced.  This can be done in the same process context
1469  *      or a forked process, or another thread,
1470  *
1471  *      The protocol callback functions are called for a handful of events
1472  *      including http requests coming in, websocket connections becoming
1473  *      established, and data arriving; it's also called periodically to allow
1474  *      async transmission.
1475  *
1476  *      HTTP requests are sent always to the FIRST protocol in @protocol, since
1477  *      at that time websocket protocol has not been negotiated.  Other
1478  *      protocols after the first one never see any HTTP callack activity.
1479  *
1480  *      The server created is a simple http server by default; part of the
1481  *      websocket standard is upgrading this http connection to a websocket one.
1482  *
1483  *      This allows the same server to provide files like scripts and favicon /
1484  *      images or whatever over http and dynamic data over websockets all in
1485  *      one place; they're all handled in the user callback.
1486  */
1487
1488 struct libwebsocket_context *
1489 libwebsocket_create_context(int port, const char *interface,
1490                                struct libwebsocket_protocols *protocols,
1491                                const char *ssl_cert_filepath,
1492                                const char *ssl_private_key_filepath,
1493                                int gid, int uid, unsigned int options)
1494 {
1495         int n;
1496         int sockfd = 0;
1497         int fd;
1498         struct sockaddr_in serv_addr, cli_addr;
1499         int opt = 1;
1500         struct libwebsocket_context *this = NULL;
1501         unsigned int slen;
1502         char *p;
1503         char hostname[1024];
1504         struct hostent *he;
1505         struct libwebsocket *wsi;
1506
1507 #ifdef LWS_OPENSSL_SUPPORT
1508         SSL_METHOD *method;
1509         char ssl_err_buf[512];
1510 #endif
1511
1512         this = malloc(sizeof(struct libwebsocket_context));
1513         if (!this) {
1514                 fprintf(stderr, "No memory for websocket context\n");
1515                 return NULL;
1516         }
1517         this->protocols = protocols;
1518         this->listen_port = port;
1519         this->http_proxy_port = 0;
1520         this->http_proxy_address[0] = '\0';
1521         this->options = options;
1522         this->fds_count = 0;
1523
1524         this->fd_random = open(SYSTEM_RANDOM_FILEPATH, O_RDONLY);
1525         if (this->fd_random < 0) {
1526                 fprintf(stderr, "Unable to open random device %s %d\n",
1527                                        SYSTEM_RANDOM_FILEPATH, this->fd_random);
1528                 return NULL;
1529         }
1530
1531         /* find canonical hostname */
1532
1533         hostname[(sizeof hostname) - 1] = '\0';
1534         gethostname(hostname, (sizeof hostname) - 1);
1535         he = gethostbyname(hostname);
1536         if (he) {
1537                 strncpy(this->canonical_hostname, he->h_name,
1538                                            sizeof this->canonical_hostname - 1);
1539                 this->canonical_hostname[sizeof this->canonical_hostname - 1] =
1540                                                                            '\0';
1541         } else
1542                 strncpy(this->canonical_hostname, hostname,
1543                                            sizeof this->canonical_hostname - 1);
1544
1545         /* split the proxy ads:port if given */
1546
1547         p = getenv("http_proxy");
1548         if (p) {
1549                 strncpy(this->http_proxy_address, p,
1550                                            sizeof this->http_proxy_address - 1);
1551                 this->http_proxy_address[
1552                                     sizeof this->http_proxy_address - 1] = '\0';
1553
1554                 p = strchr(this->http_proxy_address, ':');
1555                 if (p == NULL) {
1556                         fprintf(stderr, "http_proxy needs to be ads:port\n");
1557                         return NULL;
1558                 }
1559                 *p = '\0';
1560                 this->http_proxy_port = atoi(p + 1);
1561
1562                 fprintf(stderr, "Using proxy %s:%u\n",
1563                                 this->http_proxy_address,
1564                                                         this->http_proxy_port);
1565         }
1566
1567         if (port) {
1568
1569 #ifdef LWS_OPENSSL_SUPPORT
1570                 this->use_ssl = ssl_cert_filepath != NULL &&
1571                                                ssl_private_key_filepath != NULL;
1572                 if (this->use_ssl)
1573                         fprintf(stderr, " Compiled with SSL support, "
1574                                                                   "using it\n");
1575                 else
1576                         fprintf(stderr, " Compiled with SSL support, "
1577                                                               "not using it\n");
1578
1579 #else
1580                 if (ssl_cert_filepath != NULL &&
1581                                              ssl_private_key_filepath != NULL) {
1582                         fprintf(stderr, " Not compiled for OpenSSl support!\n");
1583                         return NULL;
1584                 }
1585                 fprintf(stderr, " Compiled without SSL support, "
1586                                                        "serving unencrypted\n");
1587 #endif
1588         }
1589
1590         /* ignore SIGPIPE */
1591
1592         signal(SIGPIPE, sigpipe_handler);
1593
1594
1595 #ifdef LWS_OPENSSL_SUPPORT
1596
1597         /* basic openssl init */
1598
1599         SSL_library_init();
1600
1601         OpenSSL_add_all_algorithms();
1602         SSL_load_error_strings();
1603
1604         this->openssl_websocket_private_data_index =
1605                 SSL_get_ex_new_index(0, "libwebsockets", NULL, NULL, NULL);
1606
1607         /*
1608          * Firefox insists on SSLv23 not SSLv3
1609          * Konq disables SSLv2 by default now, SSLv23 works
1610          */
1611
1612         method = (SSL_METHOD *)SSLv23_server_method();
1613         if (!method) {
1614                 fprintf(stderr, "problem creating ssl method: %s\n",
1615                         ERR_error_string(ERR_get_error(), ssl_err_buf));
1616                 return NULL;
1617         }
1618         this->ssl_ctx = SSL_CTX_new(method);    /* create context */
1619         if (!this->ssl_ctx) {
1620                 fprintf(stderr, "problem creating ssl context: %s\n",
1621                         ERR_error_string(ERR_get_error(), ssl_err_buf));
1622                 return NULL;
1623         }
1624
1625         /* client context */
1626
1627         method = (SSL_METHOD *)SSLv23_client_method();
1628         if (!method) {
1629                 fprintf(stderr, "problem creating ssl method: %s\n",
1630                         ERR_error_string(ERR_get_error(), ssl_err_buf));
1631                 return NULL;
1632         }
1633         this->ssl_client_ctx = SSL_CTX_new(method);     /* create context */
1634         if (!this->ssl_client_ctx) {
1635                 fprintf(stderr, "problem creating ssl context: %s\n",
1636                         ERR_error_string(ERR_get_error(), ssl_err_buf));
1637                 return NULL;
1638         }
1639
1640
1641         /* openssl init for cert verification (used with client sockets) */
1642
1643         if (!SSL_CTX_load_verify_locations(this->ssl_client_ctx, NULL,
1644                                                     LWS_OPENSSL_CLIENT_CERTS)) {
1645                 fprintf(stderr, "Unable to load SSL Client certs from %s "
1646                         "(set by --with-client-cert-dir= in configure) -- "
1647                         " client ssl isn't going to work",
1648                                                       LWS_OPENSSL_CLIENT_CERTS);
1649         }
1650
1651         /*
1652          * callback allowing user code to load extra verification certs
1653          * helping the client to verify server identity
1654          */
1655
1656         this->protocols[0].callback(this, NULL,
1657                 LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
1658                 this->ssl_client_ctx, NULL, 0);
1659
1660         /* as a server, are we requiring clients to identify themselves? */
1661
1662         if (options & LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT) {
1663
1664                 /* absolutely require the client cert */
1665                 
1666                 SSL_CTX_set_verify(this->ssl_ctx,
1667                        SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1668                                                        OpenSSL_verify_callback);
1669
1670                 /*
1671                  * give user code a chance to load certs into the server
1672                  * allowing it to verify incoming client certs
1673                  */
1674
1675                 this->protocols[0].callback(this, NULL,
1676                         LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
1677                                                         this->ssl_ctx, NULL, 0);
1678         }
1679
1680         if (this->use_ssl) {
1681
1682                 /* openssl init for server sockets */
1683
1684                 /* set the local certificate from CertFile */
1685                 n = SSL_CTX_use_certificate_file(this->ssl_ctx,
1686                                         ssl_cert_filepath, SSL_FILETYPE_PEM);
1687                 if (n != 1) {
1688                         fprintf(stderr, "problem getting cert '%s': %s\n",
1689                                 ssl_cert_filepath,
1690                                 ERR_error_string(ERR_get_error(), ssl_err_buf));
1691                         return NULL;
1692                 }
1693                 /* set the private key from KeyFile */
1694                 if (SSL_CTX_use_PrivateKey_file(this->ssl_ctx,
1695                                                 ssl_private_key_filepath,
1696                                                        SSL_FILETYPE_PEM) != 1) {
1697                         fprintf(stderr, "ssl problem getting key '%s': %s\n",
1698                                                 ssl_private_key_filepath,
1699                                 ERR_error_string(ERR_get_error(), ssl_err_buf));
1700                         return NULL;
1701                 }
1702                 /* verify private key */
1703                 if (!SSL_CTX_check_private_key(this->ssl_ctx)) {
1704                         fprintf(stderr, "Private SSL key doesn't match cert\n");
1705                         return NULL;
1706                 }
1707
1708                 /* SSL is happy and has a cert it's content with */
1709         }
1710 #endif
1711
1712         /* selftest */
1713
1714         if (lws_b64_selftest())
1715                 return NULL;
1716
1717         /* fd hashtable init */
1718
1719         for (n = 0; n < FD_HASHTABLE_MODULUS; n++)
1720                 this->fd_hashtable[n].length = 0;
1721
1722         /* set up our external listening socket we serve on */
1723
1724         if (port) {
1725
1726                 sockfd = socket(AF_INET, SOCK_STREAM, 0);
1727                 if (sockfd < 0) {
1728                         fprintf(stderr, "ERROR opening socket");
1729                         return NULL;
1730                 }
1731
1732                 /* allow us to restart even if old sockets in TIME_WAIT */
1733                 setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
1734
1735                 bzero((char *) &serv_addr, sizeof(serv_addr));
1736                 serv_addr.sin_family = AF_INET;
1737                 if (interface == NULL)
1738                         serv_addr.sin_addr.s_addr = INADDR_ANY;
1739                 else
1740                         interface_to_sa(interface, &serv_addr,
1741                                                 sizeof(serv_addr));
1742                 serv_addr.sin_port = htons(port);
1743
1744                 n = bind(sockfd, (struct sockaddr *) &serv_addr,
1745                                                              sizeof(serv_addr));
1746                 if (n < 0) {
1747                         fprintf(stderr, "ERROR on binding to port %d (%d %d)\n",
1748                                                                 port, n, errno);
1749                         return NULL;
1750                 }
1751
1752                 wsi = malloc(sizeof(struct libwebsocket));
1753                 memset(wsi, 0, sizeof (struct libwebsocket));
1754                 wsi->sock = sockfd;
1755                 wsi->mode = LWS_CONNMODE_SERVER_LISTENER;
1756                 insert_wsi(this, wsi);
1757
1758                 listen(sockfd, 5);
1759                 fprintf(stderr, " Listening on port %d\n", port);
1760
1761                 /* list in the internal poll array */
1762                 
1763                 this->fds[this->fds_count].fd = sockfd;
1764                 this->fds[this->fds_count++].events = POLLIN;
1765
1766                 /* external POLL support via protocol 0 */
1767                 this->protocols[0].callback(this, wsi,
1768                         LWS_CALLBACK_ADD_POLL_FD,
1769                         (void *)(long)sockfd, NULL, POLLIN);
1770
1771         }
1772
1773         /* drop any root privs for this process */
1774
1775         if (gid != -1)
1776                 if (setgid(gid))
1777                         fprintf(stderr, "setgid: %s\n", strerror(errno));
1778         if (uid != -1)
1779                 if (setuid(uid))
1780                         fprintf(stderr, "setuid: %s\n", strerror(errno));
1781
1782
1783         /* set up our internal broadcast trigger sockets per-protocol */
1784
1785         for (this->count_protocols = 0;
1786                         protocols[this->count_protocols].callback;
1787                                                       this->count_protocols++) {
1788                 protocols[this->count_protocols].owning_server = this;
1789                 protocols[this->count_protocols].protocol_index =
1790                                                           this->count_protocols;
1791
1792                 fd = socket(AF_INET, SOCK_STREAM, 0);
1793                 if (fd < 0) {
1794                         fprintf(stderr, "ERROR opening socket");
1795                         return NULL;
1796                 }
1797
1798                 /* allow us to restart even if old sockets in TIME_WAIT */
1799                 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
1800
1801                 bzero((char *) &serv_addr, sizeof(serv_addr));
1802                 serv_addr.sin_family = AF_INET;
1803                 serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
1804                 serv_addr.sin_port = 0; /* pick the port for us */
1805
1806                 n = bind(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
1807                 if (n < 0) {
1808                         fprintf(stderr, "ERROR on binding to port %d (%d %d)\n",
1809                                                                 port, n, errno);
1810                         return NULL;
1811                 }
1812
1813                 slen = sizeof cli_addr;
1814                 n = getsockname(fd, (struct sockaddr *)&cli_addr, &slen);
1815                 if (n < 0) {
1816                         fprintf(stderr, "getsockname failed\n");
1817                         return NULL;
1818                 }
1819                 protocols[this->count_protocols].broadcast_socket_port =
1820                                                        ntohs(cli_addr.sin_port);
1821                 listen(fd, 5);
1822
1823                 debug("  Protocol %s broadcast socket %d\n",
1824                                 protocols[this->count_protocols].name,
1825                                                       ntohs(cli_addr.sin_port));
1826
1827                 /* dummy wsi per broadcast proxy socket */
1828
1829                 wsi = malloc(sizeof(struct libwebsocket));
1830                 memset(wsi, 0, sizeof (struct libwebsocket));
1831                 wsi->sock = fd;
1832                 wsi->mode = LWS_CONNMODE_BROADCAST_PROXY_LISTENER;
1833                 /* note which protocol we are proxying */
1834                 wsi->protocol_index_for_broadcast_proxy = this->count_protocols;
1835                 insert_wsi(this, wsi);
1836
1837                 /* list in internal poll array */
1838
1839                 this->fds[this->fds_count].fd = fd;
1840                 this->fds[this->fds_count].events = POLLIN;
1841                 this->fds[this->fds_count].revents = 0;
1842                 this->fds_count++;
1843
1844                 /* external POLL support via protocol 0 */
1845                 this->protocols[0].callback(this, wsi,
1846                         LWS_CALLBACK_ADD_POLL_FD,
1847                         (void *)(long)fd, NULL, POLLIN);
1848         }
1849
1850         return this;
1851 }
1852
1853
1854 #ifndef LWS_NO_FORK
1855
1856 /**
1857  * libwebsockets_fork_service_loop() - Optional helper function forks off
1858  *                                a process for the websocket server loop.
1859  *                              You don't have to use this but if not, you
1860  *                              have to make sure you are calling
1861  *                              libwebsocket_service periodically to service
1862  *                              the websocket traffic
1863  * @this:       server context returned by creation function
1864  */
1865
1866 int
1867 libwebsockets_fork_service_loop(struct libwebsocket_context *this)
1868 {
1869         int fd;
1870         struct sockaddr_in cli_addr;
1871         int n;
1872         int p;
1873
1874         n = fork();
1875         if (n < 0)
1876                 return n;
1877
1878         if (!n) {
1879
1880                 /* main process context */
1881
1882                 /*
1883                  * set up the proxy sockets to allow broadcast from
1884                  * service process context
1885                  */
1886
1887                 for (p = 0; p < this->count_protocols; p++) {
1888                         fd = socket(AF_INET, SOCK_STREAM, 0);
1889                         if (fd < 0) {
1890                                 fprintf(stderr, "Unable to create socket\n");
1891                                 return -1;
1892                         }
1893                         cli_addr.sin_family = AF_INET;
1894                         cli_addr.sin_port = htons(
1895                              this->protocols[p].broadcast_socket_port);
1896                         cli_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
1897                         n = connect(fd, (struct sockaddr *)&cli_addr,
1898                                                                sizeof cli_addr);
1899                         if (n < 0) {
1900                                 fprintf(stderr, "Unable to connect to "
1901                                                 "broadcast socket %d, %s\n",
1902                                                 n, strerror(errno));
1903                                 return -1;
1904                         }
1905
1906                         this->protocols[p].broadcast_socket_user_fd = fd;
1907                 }
1908
1909                 return 0;
1910         }
1911
1912         /* we want a SIGHUP when our parent goes down */
1913         prctl(PR_SET_PDEATHSIG, SIGHUP);
1914
1915         /* in this forked process, sit and service websocket connections */
1916
1917         while (1)
1918                 if (libwebsocket_service(this, 1000))
1919                         return -1;
1920
1921         return 0;
1922 }
1923
1924 #endif
1925
1926 /**
1927  * libwebsockets_get_protocol() - Returns a protocol pointer from a websocket
1928  *                                connection.
1929  * @wsi:        pointer to struct websocket you want to know the protocol of
1930  *
1931  *
1932  *      This is useful to get the protocol to broadcast back to from inside
1933  * the callback.
1934  */
1935
1936 const struct libwebsocket_protocols *
1937 libwebsockets_get_protocol(struct libwebsocket *wsi)
1938 {
1939         return wsi->protocol;
1940 }
1941
1942 /**
1943  * libwebsockets_broadcast() - Sends a buffer to the callback for all active
1944  *                                connections of the given protocol.
1945  * @protocol:   pointer to the protocol you will broadcast to all members of
1946  * @buf:  buffer containing the data to be broadcase.  NOTE: this has to be
1947  *              allocated with LWS_SEND_BUFFER_PRE_PADDING valid bytes before
1948  *              the pointer and LWS_SEND_BUFFER_POST_PADDING afterwards in the
1949  *              case you are calling this function from callback context.
1950  * @len:        length of payload data in buf, starting from buf.
1951  *
1952  *      This function allows bulk sending of a packet to every connection using
1953  * the given protocol.  It does not send the data directly; instead it calls
1954  * the callback with a reason type of LWS_CALLBACK_BROADCAST.  If the callback
1955  * wants to actually send the data for that connection, the callback itself
1956  * should call libwebsocket_write().
1957  *
1958  * libwebsockets_broadcast() can be called from another fork context without
1959  * having to take any care about data visibility between the processes, it'll
1960  * "just work".
1961  */
1962
1963
1964 int
1965 libwebsockets_broadcast(const struct libwebsocket_protocols *protocol,
1966                                                  unsigned char *buf, size_t len)
1967 {
1968         struct libwebsocket_context *this = protocol->owning_server;
1969         int n;
1970         int m;
1971         struct libwebsocket * wsi;
1972
1973         if (!protocol->broadcast_socket_user_fd) {
1974                 /*
1975                  * We are either running unforked / flat, or we are being
1976                  * called from poll thread context
1977                  * eg, from a callback.  In that case don't use sockets for
1978                  * broadcast IPC (since we can't open a socket connection to
1979                  * a socket listening on our own thread) but directly do the
1980                  * send action.
1981                  *
1982                  * Locking is not needed because we are by definition being
1983                  * called in the poll thread context and are serialized.
1984                  */
1985
1986                 for (n = 0; n < FD_HASHTABLE_MODULUS; n++) {
1987
1988                         for (m = 0; m < this->fd_hashtable[n].length; m++) {
1989
1990                                 wsi = this->fd_hashtable[n].wsi[m];
1991
1992                                 if (wsi->mode != LWS_CONNMODE_WS_SERVING)
1993                                         continue;
1994
1995                                 /*
1996                                  * never broadcast to
1997                                  * non-established connections
1998                                  */
1999                                 if (wsi->state != WSI_STATE_ESTABLISHED)
2000                                         continue;
2001
2002                                 /* only broadcast to guys using
2003                                  * requested protocol
2004                                  */
2005                                 if (wsi->protocol != protocol)
2006                                         continue;
2007
2008                                 wsi->protocol->callback(this, wsi,
2009                                          LWS_CALLBACK_BROADCAST,
2010                                          wsi->user_space,
2011                                          buf, len);
2012                         }
2013                 }
2014
2015                 return 0;
2016         }
2017
2018         /*
2019          * We're being called from a different process context than the server
2020          * loop.  Instead of broadcasting directly, we send our
2021          * payload on a socket to do the IPC; the server process will serialize
2022          * the broadcast action in its main poll() loop.
2023          *
2024          * There's one broadcast socket listening for each protocol supported
2025          * set up when the websocket server initializes
2026          */
2027
2028         n = send(protocol->broadcast_socket_user_fd, buf, len, MSG_NOSIGNAL);
2029
2030         return n;
2031 }