]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/bhyve/rfb.c
Merge ^/head r319548 through r319778.
[FreeBSD/FreeBSD.git] / usr.sbin / bhyve / rfb.c
1 /*-
2  * Copyright (c) 2015 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com>
3  * Copyright (c) 2015 Leon Dang
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include <sys/param.h>
32 #ifndef WITHOUT_CAPSICUM
33 #include <sys/capsicum.h>
34 #endif
35 #include <sys/socket.h>
36 #include <sys/select.h>
37 #include <sys/time.h>
38 #include <arpa/inet.h>
39 #include <machine/cpufunc.h>
40 #include <machine/specialreg.h>
41 #include <netinet/in.h>
42
43 #include <assert.h>
44 #include <err.h>
45 #include <errno.h>
46 #include <pthread.h>
47 #include <pthread_np.h>
48 #include <signal.h>
49 #include <stdbool.h>
50 #include <stdlib.h>
51 #include <stdio.h>
52 #include <string.h>
53 #include <sysexits.h>
54 #include <unistd.h>
55
56 #include <zlib.h>
57
58 #include "bhyvegc.h"
59 #include "console.h"
60 #include "rfb.h"
61 #include "sockstream.h"
62
63 #ifndef NO_OPENSSL
64 #include <openssl/des.h>
65 #endif
66
67 static int rfb_debug = 0;
68 #define DPRINTF(params) if (rfb_debug) printf params
69 #define WPRINTF(params) printf params
70
71 #define AUTH_LENGTH     16
72 #define PASSWD_LENGTH   8
73
74 #define SECURITY_TYPE_NONE 1
75 #define SECURITY_TYPE_VNC_AUTH 2
76
77 #define AUTH_FAILED_UNAUTH 1
78 #define AUTH_FAILED_ERROR 2
79
80 struct rfb_softc {
81         int             sfd;
82         pthread_t       tid;
83
84         int             cfd;
85
86         int             width, height;
87
88         char            *password;
89
90         bool    enc_raw_ok;
91         bool    enc_zlib_ok;
92         bool    enc_resize_ok;
93
94         z_stream        zstream;
95         uint8_t         *zbuf;
96         int             zbuflen;
97
98         int             conn_wait;
99         int             sending;
100         pthread_mutex_t mtx;
101         pthread_cond_t  cond;
102
103         int             hw_crc;
104         uint32_t        *crc;           /* WxH crc cells */
105         uint32_t        *crc_tmp;       /* buffer to store single crc row */
106         int             crc_width, crc_height;
107 };
108
109 struct rfb_pixfmt {
110         uint8_t         bpp;
111         uint8_t         depth;
112         uint8_t         bigendian;
113         uint8_t         truecolor;
114         uint16_t        red_max;
115         uint16_t        green_max;
116         uint16_t        blue_max;
117         uint8_t         red_shift;
118         uint8_t         green_shift;
119         uint8_t         blue_shift;
120         uint8_t         pad[3];
121 };
122
123 struct rfb_srvr_info {
124         uint16_t                width;
125         uint16_t                height;
126         struct rfb_pixfmt       pixfmt;
127         uint32_t                namelen;
128 };
129
130 struct rfb_pixfmt_msg {
131         uint8_t                 type;
132         uint8_t                 pad[3];
133         struct rfb_pixfmt       pixfmt;
134 };
135
136 #define RFB_ENCODING_RAW                0
137 #define RFB_ENCODING_ZLIB               6
138 #define RFB_ENCODING_RESIZE             -223
139
140 #define RFB_MAX_WIDTH                   2000
141 #define RFB_MAX_HEIGHT                  1200
142 #define RFB_ZLIB_BUFSZ                  RFB_MAX_WIDTH*RFB_MAX_HEIGHT*4
143
144 /* percentage changes to screen before sending the entire screen */
145 #define RFB_SEND_ALL_THRESH             25
146
147 struct rfb_enc_msg {
148         uint8_t         type;
149         uint8_t         pad;
150         uint16_t        numencs;
151 };
152
153 struct rfb_updt_msg {
154         uint8_t         type;
155         uint8_t         incremental;
156         uint16_t        x;
157         uint16_t        y;
158         uint16_t        width;
159         uint16_t        height;
160 };
161
162 struct rfb_key_msg {
163         uint8_t         type;
164         uint8_t         down;
165         uint16_t        pad;
166         uint32_t        code;
167 };
168
169 struct rfb_ptr_msg {
170         uint8_t         type;
171         uint8_t         button;
172         uint16_t        x;
173         uint16_t        y;
174 };
175
176 struct rfb_srvr_updt_msg {
177         uint8_t         type;
178         uint8_t         pad;
179         uint16_t        numrects;
180 };
181
182 struct rfb_srvr_rect_hdr {
183         uint16_t        x;
184         uint16_t        y;
185         uint16_t        width;
186         uint16_t        height;
187         uint32_t        encoding;
188 };
189
190 struct rfb_cuttext_msg {
191         uint8_t         type;
192         uint8_t         padding[3];
193         uint32_t        length;
194 };
195
196
197 static void
198 rfb_send_server_init_msg(int cfd)
199 {
200         struct bhyvegc_image *gc_image;
201         struct rfb_srvr_info sinfo;
202
203         gc_image = console_get_image();
204
205         sinfo.width = htons(gc_image->width);
206         sinfo.height = htons(gc_image->height);
207         sinfo.pixfmt.bpp = 32;
208         sinfo.pixfmt.depth = 32;
209         sinfo.pixfmt.bigendian = 0;
210         sinfo.pixfmt.truecolor = 1;
211         sinfo.pixfmt.red_max = htons(255);
212         sinfo.pixfmt.green_max = htons(255);
213         sinfo.pixfmt.blue_max = htons(255);
214         sinfo.pixfmt.red_shift = 16;
215         sinfo.pixfmt.green_shift = 8;
216         sinfo.pixfmt.blue_shift = 0;
217         sinfo.namelen = htonl(strlen("bhyve"));
218         (void)stream_write(cfd, &sinfo, sizeof(sinfo));
219         (void)stream_write(cfd, "bhyve", strlen("bhyve"));
220 }
221
222 static void
223 rfb_send_resize_update_msg(struct rfb_softc *rc, int cfd)
224 {
225         struct rfb_srvr_updt_msg supdt_msg;
226         struct rfb_srvr_rect_hdr srect_hdr;
227
228         /* Number of rectangles: 1 */
229         supdt_msg.type = 0;
230         supdt_msg.pad = 0;
231         supdt_msg.numrects = htons(1);
232         stream_write(cfd, &supdt_msg, sizeof(struct rfb_srvr_updt_msg));
233
234         /* Rectangle header */
235         srect_hdr.x = htons(0);
236         srect_hdr.y = htons(0);
237         srect_hdr.width = htons(rc->width);
238         srect_hdr.height = htons(rc->height);
239         srect_hdr.encoding = htonl(RFB_ENCODING_RESIZE);
240         stream_write(cfd, &srect_hdr, sizeof(struct rfb_srvr_rect_hdr));
241 }
242
243 static void
244 rfb_recv_set_pixfmt_msg(struct rfb_softc *rc, int cfd)
245 {
246         struct rfb_pixfmt_msg pixfmt_msg;
247
248         (void)stream_read(cfd, ((void *)&pixfmt_msg)+1, sizeof(pixfmt_msg)-1);
249 }
250
251
252 static void
253 rfb_recv_set_encodings_msg(struct rfb_softc *rc, int cfd)
254 {
255         struct rfb_enc_msg enc_msg;
256         int i;
257         uint32_t encoding;
258
259         assert((sizeof(enc_msg) - 1) == 3);
260         (void)stream_read(cfd, ((void *)&enc_msg)+1, sizeof(enc_msg)-1);
261
262         for (i = 0; i < htons(enc_msg.numencs); i++) {
263                 (void)stream_read(cfd, &encoding, sizeof(encoding));
264                 switch (htonl(encoding)) {
265                 case RFB_ENCODING_RAW:
266                         rc->enc_raw_ok = true;
267                         break;
268                 case RFB_ENCODING_ZLIB:
269                         rc->enc_zlib_ok = true;
270                         deflateInit(&rc->zstream, Z_BEST_SPEED);
271                         break;
272                 case RFB_ENCODING_RESIZE:
273                         rc->enc_resize_ok = true;
274                         break;
275                 }
276         }
277 }
278
279 /*
280  * Calculate CRC32 using SSE4.2; Intel or AMD Bulldozer+ CPUs only
281  */
282 static __inline uint32_t
283 fast_crc32(void *buf, int len, uint32_t crcval)
284 {
285         uint32_t q = len / sizeof(uint32_t);
286         uint32_t *p = (uint32_t *)buf;
287
288         while (q--) {
289                 asm volatile (
290                         ".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
291                         :"=S" (crcval)
292                         :"0" (crcval), "c" (*p)
293                 );
294                 p++;
295         }
296
297         return (crcval);
298 }
299
300
301 static int
302 rfb_send_rect(struct rfb_softc *rc, int cfd, struct bhyvegc_image *gc,
303               int x, int y, int w, int h)
304 {
305         struct rfb_srvr_updt_msg supdt_msg;
306         struct rfb_srvr_rect_hdr srect_hdr;
307         unsigned long zlen;
308         ssize_t nwrite, total;
309         int err;
310         uint32_t *p;
311         uint8_t *zbufp;
312
313         /*
314          * Send a single rectangle of the given x, y, w h dimensions.
315          */
316
317         /* Number of rectangles: 1 */
318         supdt_msg.type = 0;
319         supdt_msg.pad = 0;
320         supdt_msg.numrects = htons(1);
321         nwrite = stream_write(cfd, &supdt_msg,
322                               sizeof(struct rfb_srvr_updt_msg));
323         if (nwrite <= 0)
324                 return (nwrite);
325
326
327         /* Rectangle header */
328         srect_hdr.x = htons(x);
329         srect_hdr.y = htons(y);
330         srect_hdr.width = htons(w);
331         srect_hdr.height = htons(h);
332
333         h = y + h;
334         w *= sizeof(uint32_t);
335         if (rc->enc_zlib_ok) {
336                 zbufp = rc->zbuf;
337                 rc->zstream.total_in = 0;
338                 rc->zstream.total_out = 0;
339                 for (p = &gc->data[y * gc->width + x]; y < h; y++) {
340                         rc->zstream.next_in = (Bytef *)p;
341                         rc->zstream.avail_in = w;
342                         rc->zstream.next_out = (Bytef *)zbufp;
343                         rc->zstream.avail_out = RFB_ZLIB_BUFSZ + 16 -
344                                                 rc->zstream.total_out;
345                         rc->zstream.data_type = Z_BINARY;
346
347                         /* Compress with zlib */
348                         err = deflate(&rc->zstream, Z_SYNC_FLUSH);
349                         if (err != Z_OK) {
350                                 WPRINTF(("zlib[rect] deflate err: %d\n", err));
351                                 rc->enc_zlib_ok = false;
352                                 deflateEnd(&rc->zstream);
353                                 goto doraw;
354                         }
355                         zbufp = rc->zbuf + rc->zstream.total_out;
356                         p += gc->width;
357                 }
358                 srect_hdr.encoding = htonl(RFB_ENCODING_ZLIB);
359                 nwrite = stream_write(cfd, &srect_hdr,
360                                       sizeof(struct rfb_srvr_rect_hdr));
361                 if (nwrite <= 0)
362                         return (nwrite);
363
364                 zlen = htonl(rc->zstream.total_out);
365                 nwrite = stream_write(cfd, &zlen, sizeof(uint32_t));
366                 if (nwrite <= 0)
367                         return (nwrite);
368                 return (stream_write(cfd, rc->zbuf, rc->zstream.total_out));
369         }
370
371 doraw:
372
373         total = 0;
374         zbufp = rc->zbuf;
375         for (p = &gc->data[y * gc->width + x]; y < h; y++) {
376                 memcpy(zbufp, p, w);
377                 zbufp += w;
378                 total += w;
379                 p += gc->width;
380         }
381
382         srect_hdr.encoding = htonl(RFB_ENCODING_RAW);
383         nwrite = stream_write(cfd, &srect_hdr,
384                               sizeof(struct rfb_srvr_rect_hdr));
385         if (nwrite <= 0)
386                 return (nwrite);
387
388         total = stream_write(cfd, rc->zbuf, total);
389
390         return (total);
391 }
392
393 static int
394 rfb_send_all(struct rfb_softc *rc, int cfd, struct bhyvegc_image *gc)
395 {
396         struct rfb_srvr_updt_msg supdt_msg;
397         struct rfb_srvr_rect_hdr srect_hdr;
398         ssize_t nwrite;
399         unsigned long zlen;
400         int err;
401
402         /*
403          * Send the whole thing
404          */
405
406         /* Number of rectangles: 1 */
407         supdt_msg.type = 0;
408         supdt_msg.pad = 0;
409         supdt_msg.numrects = htons(1);
410         nwrite = stream_write(cfd, &supdt_msg,
411                               sizeof(struct rfb_srvr_updt_msg));
412         if (nwrite <= 0)
413                 return (nwrite);
414
415         /* Rectangle header */
416         srect_hdr.x = 0;
417         srect_hdr.y = 0;
418         srect_hdr.width = htons(gc->width);
419         srect_hdr.height = htons(gc->height);
420         if (rc->enc_zlib_ok) {
421                 rc->zstream.next_in = (Bytef *)gc->data;
422                 rc->zstream.avail_in = gc->width * gc->height *
423                                    sizeof(uint32_t);
424                 rc->zstream.next_out = (Bytef *)rc->zbuf;
425                 rc->zstream.avail_out = RFB_ZLIB_BUFSZ + 16;
426                 rc->zstream.data_type = Z_BINARY;
427
428                 rc->zstream.total_in = 0;
429                 rc->zstream.total_out = 0;
430
431                 /* Compress with zlib */
432                 err = deflate(&rc->zstream, Z_SYNC_FLUSH);
433                 if (err != Z_OK) {
434                         WPRINTF(("zlib deflate err: %d\n", err));
435                         rc->enc_zlib_ok = false;
436                         deflateEnd(&rc->zstream);
437                         goto doraw;
438                 }
439
440                 srect_hdr.encoding = htonl(RFB_ENCODING_ZLIB);
441                 nwrite = stream_write(cfd, &srect_hdr,
442                                       sizeof(struct rfb_srvr_rect_hdr));
443                 if (nwrite <= 0)
444                         return (nwrite);
445
446                 zlen = htonl(rc->zstream.total_out);
447                 nwrite = stream_write(cfd, &zlen, sizeof(uint32_t));
448                 if (nwrite <= 0)
449                         return (nwrite);
450                 return (stream_write(cfd, rc->zbuf, rc->zstream.total_out));
451         }
452
453 doraw:
454         srect_hdr.encoding = htonl(RFB_ENCODING_RAW);
455         nwrite = stream_write(cfd, &srect_hdr,
456                               sizeof(struct rfb_srvr_rect_hdr));
457         if (nwrite <= 0)
458                 return (nwrite);
459
460         nwrite = stream_write(cfd, gc->data,
461                        gc->width * gc->height * sizeof(uint32_t));
462
463         return (nwrite);
464 }
465
466 #define PIX_PER_CELL    32
467 #define PIXCELL_SHIFT   5
468 #define PIXCELL_MASK    0x1F
469
470 static int
471 rfb_send_screen(struct rfb_softc *rc, int cfd, int all)
472 {
473         struct bhyvegc_image *gc_image;
474         ssize_t nwrite;
475         int x, y;
476         int celly, cellwidth;
477         int xcells, ycells;
478         int w, h;
479         uint32_t *p;
480         int rem_x, rem_y;   /* remainder for resolutions not x32 pixels ratio */
481         int retval;
482         uint32_t *crc_p, *orig_crc;
483         int changes;
484
485         console_refresh();
486         gc_image = console_get_image();
487
488         pthread_mutex_lock(&rc->mtx);
489         if (rc->sending) {
490                 pthread_mutex_unlock(&rc->mtx);
491                 return (1);
492         }
493         rc->sending = 1;
494         pthread_mutex_unlock(&rc->mtx);
495
496         retval = 0;
497
498         if (all) {
499                 retval = rfb_send_all(rc, cfd, gc_image);
500                 goto done;
501         }
502
503         /*
504          * Calculate the checksum for each 32x32 cell. Send each that
505          * has changed since the last scan.
506          */
507
508         /* Resolution changed */
509
510         rc->crc_width = gc_image->width;
511         rc->crc_height = gc_image->height;
512
513         w = rc->crc_width;
514         h = rc->crc_height;
515         xcells = howmany(rc->crc_width, PIX_PER_CELL);
516         ycells = howmany(rc->crc_height, PIX_PER_CELL);
517
518         rem_x = w & PIXCELL_MASK;
519
520         rem_y = h & PIXCELL_MASK;
521         if (!rem_y)
522                 rem_y = PIX_PER_CELL;
523
524         p = gc_image->data;
525
526         /*
527          * Go through all cells and calculate crc. If significant number
528          * of changes, then send entire screen.
529          * crc_tmp is dual purpose: to store the new crc and to flag as
530          * a cell that has changed.
531          */
532         crc_p = rc->crc_tmp - xcells;
533         orig_crc = rc->crc - xcells;
534         changes = 0;
535         memset(rc->crc_tmp, 0, sizeof(uint32_t) * xcells * ycells);
536         for (y = 0; y < h; y++) {
537                 if ((y & PIXCELL_MASK) == 0) {
538                         crc_p += xcells;
539                         orig_crc += xcells;
540                 }
541
542                 for (x = 0; x < xcells; x++) {
543                         if (rc->hw_crc)
544                                 crc_p[x] = fast_crc32(p,
545                                              PIX_PER_CELL * sizeof(uint32_t),
546                                              crc_p[x]);
547                         else
548                                 crc_p[x] = (uint32_t)crc32(crc_p[x],
549                                              (Bytef *)p,
550                                              PIX_PER_CELL * sizeof(uint32_t));
551
552                         p += PIX_PER_CELL;
553
554                         /* check for crc delta if last row in cell */
555                         if ((y & PIXCELL_MASK) == PIXCELL_MASK || y == (h-1)) {
556                                 if (orig_crc[x] != crc_p[x]) {
557                                         orig_crc[x] = crc_p[x];
558                                         crc_p[x] = 1;
559                                         changes++;
560                                 } else {
561                                         crc_p[x] = 0;
562                                 }
563                         }
564                 }
565
566                 if (rem_x) {
567                         if (rc->hw_crc)
568                                 crc_p[x] = fast_crc32(p,
569                                                     rem_x * sizeof(uint32_t),
570                                                     crc_p[x]);
571                         else
572                                 crc_p[x] = (uint32_t)crc32(crc_p[x],
573                                                     (Bytef *)p,
574                                                     rem_x * sizeof(uint32_t));
575                         p += rem_x;
576
577                         if ((y & PIXCELL_MASK) == PIXCELL_MASK || y == (h-1)) {
578                                 if (orig_crc[x] != crc_p[x]) {
579                                         orig_crc[x] = crc_p[x];
580                                         crc_p[x] = 1;
581                                         changes++;
582                                 } else {
583                                         crc_p[x] = 0;
584                                 }
585                         }
586                 }
587         }
588
589         /* If number of changes is > THRESH percent, send the whole screen */
590         if (((changes * 100) / (xcells * ycells)) >= RFB_SEND_ALL_THRESH) {
591                 retval = rfb_send_all(rc, cfd, gc_image);
592                 goto done;
593         }
594         
595         /* Go through all cells, and send only changed ones */
596         crc_p = rc->crc_tmp;
597         for (y = 0; y < h; y += PIX_PER_CELL) {
598                 /* previous cell's row */
599                 celly = (y >> PIXCELL_SHIFT);
600
601                 /* Delta check crc to previous set */
602                 for (x = 0; x < xcells; x++) {
603                         if (*crc_p++ == 0)
604                                 continue;
605
606                         if (x == (xcells - 1) && rem_x > 0)
607                                 cellwidth = rem_x;
608                         else
609                                 cellwidth = PIX_PER_CELL;
610                         nwrite = rfb_send_rect(rc, cfd,
611                                 gc_image,
612                                 x * PIX_PER_CELL,
613                                 celly * PIX_PER_CELL,
614                                 cellwidth,
615                                 y + PIX_PER_CELL >= h ? rem_y : PIX_PER_CELL);
616                         if (nwrite <= 0) {
617                                 retval = nwrite;
618                                 goto done;
619                         }
620                 }
621         }
622         retval = 1;
623
624 done:
625         pthread_mutex_lock(&rc->mtx);
626         rc->sending = 0;
627         pthread_mutex_unlock(&rc->mtx);
628         
629         return (retval);
630 }
631
632
633 static void
634 rfb_recv_update_msg(struct rfb_softc *rc, int cfd, int discardonly)
635 {
636         struct rfb_updt_msg updt_msg;
637         struct bhyvegc_image *gc_image;
638
639         (void)stream_read(cfd, ((void *)&updt_msg) + 1 , sizeof(updt_msg) - 1);
640
641         console_refresh();
642         gc_image = console_get_image();
643
644         updt_msg.x = htons(updt_msg.x);
645         updt_msg.y = htons(updt_msg.y);
646         updt_msg.width = htons(updt_msg.width);
647         updt_msg.height = htons(updt_msg.height);
648
649         if (updt_msg.width != gc_image->width ||
650             updt_msg.height != gc_image->height) {
651                 rc->width = gc_image->width;
652                 rc->height = gc_image->height;
653                 if (rc->enc_resize_ok)
654                         rfb_send_resize_update_msg(rc, cfd);
655         }
656
657         if (discardonly)
658                 return;
659
660         rfb_send_screen(rc, cfd, 1);
661 }
662
663 static void
664 rfb_recv_key_msg(struct rfb_softc *rc, int cfd)
665 {
666         struct rfb_key_msg key_msg;
667
668         (void)stream_read(cfd, ((void *)&key_msg) + 1, sizeof(key_msg) - 1);
669
670         console_key_event(key_msg.down, htonl(key_msg.code));
671 }
672
673 static void
674 rfb_recv_ptr_msg(struct rfb_softc *rc, int cfd)
675 {
676         struct rfb_ptr_msg ptr_msg;
677
678         (void)stream_read(cfd, ((void *)&ptr_msg) + 1, sizeof(ptr_msg) - 1);
679
680         console_ptr_event(ptr_msg.button, htons(ptr_msg.x), htons(ptr_msg.y));
681 }
682
683 static void
684 rfb_recv_cuttext_msg(struct rfb_softc *rc, int cfd)
685 {
686         struct rfb_cuttext_msg ct_msg;
687         unsigned char buf[32];
688         int len;
689
690         len = stream_read(cfd, ((void *)&ct_msg) + 1, sizeof(ct_msg) - 1);
691         ct_msg.length = htonl(ct_msg.length);
692         while (ct_msg.length > 0) {
693                 len = stream_read(cfd, buf, ct_msg.length > sizeof(buf) ?
694                         sizeof(buf) : ct_msg.length);
695                 ct_msg.length -= len;
696         }
697 }
698
699 static int64_t
700 timeval_delta(struct timeval *prev, struct timeval *now)
701 {
702         int64_t n1, n2;
703         n1 = now->tv_sec * 1000000 + now->tv_usec;
704         n2 = prev->tv_sec * 1000000 + prev->tv_usec;
705         return (n1 - n2);
706 }
707
708 static void *
709 rfb_wr_thr(void *arg)
710 {
711         struct rfb_softc *rc;
712         fd_set rfds;
713         struct timeval tv;
714         struct timeval prev_tv;
715         int64_t tdiff;
716         int cfd;
717         int err;
718
719         rc = arg;
720         cfd = rc->cfd;
721
722         prev_tv.tv_sec = 0;
723         prev_tv.tv_usec = 0;
724         while (rc->cfd >= 0) {
725                 FD_ZERO(&rfds);
726                 FD_SET(cfd, &rfds);
727                 tv.tv_sec = 0;
728                 tv.tv_usec = 10000;
729
730                 err = select(cfd+1, &rfds, NULL, NULL, &tv);
731                 if (err < 0)
732                         return (NULL);
733
734                 /* Determine if its time to push screen; ~24hz */
735                 gettimeofday(&tv, NULL);
736                 tdiff = timeval_delta(&prev_tv, &tv);
737                 if (tdiff > 40000) {
738                         prev_tv.tv_sec = tv.tv_sec;
739                         prev_tv.tv_usec = tv.tv_usec;
740                         if (rfb_send_screen(rc, cfd, 0) <= 0) {
741                                 return (NULL);
742                         }
743                 } else {
744                         /* sleep */
745                         usleep(40000 - tdiff);
746                 }
747         }
748
749         return (NULL);
750 }
751
752 void
753 rfb_handle(struct rfb_softc *rc, int cfd)
754 {
755         const char *vbuf = "RFB 003.008\n";
756         unsigned char buf[80];
757         unsigned char *message;
758
759 #ifndef NO_OPENSSL
760         unsigned char challenge[AUTH_LENGTH];
761         unsigned char keystr[PASSWD_LENGTH];
762         unsigned char crypt_expected[AUTH_LENGTH];
763
764         DES_key_schedule ks;
765         int i;
766 #endif
767
768         pthread_t tid;
769         uint32_t sres;
770         int len;
771
772         rc->cfd = cfd;
773
774         /* 1a. Send server version */
775         stream_write(cfd, vbuf, strlen(vbuf));
776
777         /* 1b. Read client version */
778         len = read(cfd, buf, sizeof(buf));
779
780         /* 2a. Send security type */
781         buf[0] = 1;
782 #ifndef NO_OPENSSL
783         if (rc->password) 
784                 buf[1] = SECURITY_TYPE_VNC_AUTH;
785         else
786                 buf[1] = SECURITY_TYPE_NONE;
787 #else
788         buf[1] = SECURITY_TYPE_NONE;
789 #endif
790
791         stream_write(cfd, buf, 2);
792
793         /* 2b. Read agreed security type */
794         len = stream_read(cfd, buf, 1);
795
796         /* 2c. Do VNC authentication */
797         switch (buf[0]) {
798         case SECURITY_TYPE_NONE:
799                 sres = 0;
800                 break;
801         case SECURITY_TYPE_VNC_AUTH:
802                 /*
803                  * The client encrypts the challenge with DES, using a password
804                  * supplied by the user as the key.
805                  * To form the key, the password is truncated to
806                  * eight characters, or padded with null bytes on the right.
807                  * The client then sends the resulting 16-bytes response.
808                  */
809 #ifndef NO_OPENSSL
810                 strncpy(keystr, rc->password, PASSWD_LENGTH);
811
812                 /* VNC clients encrypts the challenge with all the bit fields
813                  * in each byte of the password mirrored.
814                  * Here we flip each byte of the keystr.
815                  */
816                 for (i = 0; i < PASSWD_LENGTH; i++) {
817                         keystr[i] = (keystr[i] & 0xF0) >> 4
818                                   | (keystr[i] & 0x0F) << 4;
819                         keystr[i] = (keystr[i] & 0xCC) >> 2
820                                   | (keystr[i] & 0x33) << 2;
821                         keystr[i] = (keystr[i] & 0xAA) >> 1
822                                   | (keystr[i] & 0x55) << 1;
823                 }
824
825                 /* Initialize a 16-byte random challenge */
826                 arc4random_buf(challenge, sizeof(challenge));
827                 stream_write(cfd, challenge, AUTH_LENGTH);
828
829                 /* Receive the 16-byte challenge response */
830                 stream_read(cfd, buf, AUTH_LENGTH);
831
832                 memcpy(crypt_expected, challenge, AUTH_LENGTH);
833
834                 /* Encrypt the Challenge with DES */
835                 DES_set_key((const_DES_cblock *)keystr, &ks);
836                 DES_ecb_encrypt((const_DES_cblock *)challenge,
837                                 (const_DES_cblock *)crypt_expected,
838                                 &ks, DES_ENCRYPT);
839                 DES_ecb_encrypt((const_DES_cblock *)(challenge + PASSWD_LENGTH),
840                                 (const_DES_cblock *)(crypt_expected +
841                                 PASSWD_LENGTH),
842                                 &ks, DES_ENCRYPT);
843
844                 if (memcmp(crypt_expected, buf, AUTH_LENGTH) != 0) {
845                         message = "Auth Failed: Invalid Password.";
846                         sres = htonl(1);
847                 } else
848                         sres = 0;
849 #else
850                 sres = 0;
851                 WPRINTF(("Auth not supported, no OpenSSL in your system"));
852 #endif
853
854                 break;
855         }
856
857         /* 2d. Write back a status */
858         stream_write(cfd, &sres, 4);
859
860         if (sres) {
861                 *((uint32_t *) buf) = htonl(strlen(message));
862                 stream_write(cfd, buf, 4);
863                 stream_write(cfd, message, strlen(message));
864                 goto done;
865         }
866
867         /* 3a. Read client shared-flag byte */
868         len = stream_read(cfd, buf, 1);
869
870         /* 4a. Write server-init info */
871         rfb_send_server_init_msg(cfd);
872
873         if (!rc->zbuf) {
874                 rc->zbuf = malloc(RFB_ZLIB_BUFSZ + 16);
875                 assert(rc->zbuf != NULL);
876         }
877
878         rfb_send_screen(rc, cfd, 1);
879
880         pthread_create(&tid, NULL, rfb_wr_thr, rc);
881         pthread_set_name_np(tid, "rfbout");
882
883         /* Now read in client requests. 1st byte identifies type */
884         for (;;) {
885                 len = read(cfd, buf, 1);
886                 if (len <= 0) {
887                         DPRINTF(("rfb client exiting\r\n"));
888                         break;
889                 }
890
891                 switch (buf[0]) {
892                 case 0:
893                         rfb_recv_set_pixfmt_msg(rc, cfd);
894                         break;
895                 case 2:
896                         rfb_recv_set_encodings_msg(rc, cfd);
897                         break;
898                 case 3:
899                         rfb_recv_update_msg(rc, cfd, 1);
900                         break;
901                 case 4:
902                         rfb_recv_key_msg(rc, cfd);
903                         break;
904                 case 5:
905                         rfb_recv_ptr_msg(rc, cfd);
906                         break;
907                 case 6:
908                         rfb_recv_cuttext_msg(rc, cfd);
909                         break;
910                 default:
911                         WPRINTF(("rfb unknown cli-code %d!\n", buf[0] & 0xff));
912                         goto done;
913                 }
914         }
915 done:
916         rc->cfd = -1;
917         pthread_join(tid, NULL);
918         if (rc->enc_zlib_ok)
919                 deflateEnd(&rc->zstream);
920 }
921
922 static void *
923 rfb_thr(void *arg)
924 {
925         struct rfb_softc *rc;
926         sigset_t set;
927
928         int cfd;
929
930         rc = arg;
931
932         sigemptyset(&set);
933         sigaddset(&set, SIGPIPE);
934         if (pthread_sigmask(SIG_BLOCK, &set, NULL) != 0) {
935                 perror("pthread_sigmask");
936                 return (NULL);
937         }
938
939         for (;;) {
940                 rc->enc_raw_ok = false;
941                 rc->enc_zlib_ok = false;
942                 rc->enc_resize_ok = false;
943
944                 cfd = accept(rc->sfd, NULL, NULL);
945                 if (rc->conn_wait) {
946                         pthread_mutex_lock(&rc->mtx);
947                         pthread_cond_signal(&rc->cond);
948                         pthread_mutex_unlock(&rc->mtx);
949                         rc->conn_wait = 0;
950                 }
951                 rfb_handle(rc, cfd);
952                 close(cfd);
953         }
954
955         /* NOTREACHED */
956         return (NULL);
957 }
958
959 static int
960 sse42_supported(void)
961 {
962         u_int cpu_registers[4], ecx;
963
964         do_cpuid(1, cpu_registers);
965
966         ecx = cpu_registers[2];
967
968         return ((ecx & CPUID2_SSE42) != 0);
969 }
970
971 int
972 rfb_init(char *hostname, int port, int wait, char *password)
973 {
974         struct rfb_softc *rc;
975         struct sockaddr_in sin;
976         int on = 1;
977 #ifndef WITHOUT_CAPSICUM
978         cap_rights_t rights;
979 #endif
980
981         rc = calloc(1, sizeof(struct rfb_softc));
982
983         rc->crc = calloc(howmany(RFB_MAX_WIDTH * RFB_MAX_HEIGHT, 32),
984                          sizeof(uint32_t));
985         rc->crc_tmp = calloc(howmany(RFB_MAX_WIDTH * RFB_MAX_HEIGHT, 32),
986                              sizeof(uint32_t));
987         rc->crc_width = RFB_MAX_WIDTH;
988         rc->crc_height = RFB_MAX_HEIGHT;
989
990         rc->password = password;
991
992         rc->sfd = socket(AF_INET, SOCK_STREAM, 0);
993         if (rc->sfd < 0) {
994                 perror("socket");
995                 return (-1);
996         }
997
998         setsockopt(rc->sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
999
1000         sin.sin_len = sizeof(sin);
1001         sin.sin_family = AF_INET;
1002         sin.sin_port = port ? htons(port) : htons(5900);
1003         if (hostname && strlen(hostname) > 0)
1004                 inet_pton(AF_INET, hostname, &(sin.sin_addr));
1005         else
1006                 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1007
1008         if (bind(rc->sfd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
1009                 perror("bind");
1010                 return (-1);
1011         }
1012
1013         if (listen(rc->sfd, 1) < 0) {
1014                 perror("listen");
1015                 return (-1);
1016         }
1017
1018 #ifndef WITHOUT_CAPSICUM
1019         cap_rights_init(&rights, CAP_ACCEPT, CAP_EVENT, CAP_READ, CAP_WRITE);
1020         if (cap_rights_limit(rc->sfd, &rights) == -1 && errno != ENOSYS)
1021                 errx(EX_OSERR, "Unable to apply rights for sandbox");
1022 #endif
1023
1024         rc->hw_crc = sse42_supported();
1025
1026         rc->conn_wait = wait;
1027         if (wait) {
1028                 pthread_mutex_init(&rc->mtx, NULL);
1029                 pthread_cond_init(&rc->cond, NULL);
1030         }
1031
1032         pthread_create(&rc->tid, NULL, rfb_thr, rc);
1033         pthread_set_name_np(rc->tid, "rfb");
1034
1035         if (wait) {
1036                 DPRINTF(("Waiting for rfb client...\n"));
1037                 pthread_mutex_lock(&rc->mtx);
1038                 pthread_cond_wait(&rc->cond, &rc->mtx);
1039                 pthread_mutex_unlock(&rc->mtx);
1040         }
1041
1042         return (0);
1043 }