View | Details | Raw Unified | Return to bug 250795 | Differences between
and this patch

Collapse All | Expand All

(-)rfb.c (-77 / +141 lines)
Lines 106-111 Link Here
106
106
107
	int		conn_wait;
107
	int		conn_wait;
108
	int		sending;
108
	int		sending;
109
	int		pending;
110
	int		update_all;
109
	pthread_mutex_t mtx;
111
	pthread_mutex_t mtx;
110
	pthread_cond_t  cond;
112
	pthread_cond_t  cond;
111
113
Lines 202-208 Link Here
202
	uint32_t	length;
204
	uint32_t	length;
203
};
205
};
204
206
205
206
static void
207
static void
207
rfb_send_server_init_msg(int cfd)
208
rfb_send_server_init_msg(int cfd)
208
{
209
{
Lines 223-228 Link Here
223
	sinfo.pixfmt.red_shift = 16;
224
	sinfo.pixfmt.red_shift = 16;
224
	sinfo.pixfmt.green_shift = 8;
225
	sinfo.pixfmt.green_shift = 8;
225
	sinfo.pixfmt.blue_shift = 0;
226
	sinfo.pixfmt.blue_shift = 0;
227
	sinfo.pixfmt.pad[0] = 0;
228
	sinfo.pixfmt.pad[1] = 0;
229
	sinfo.pixfmt.pad[2] = 0;
226
	sinfo.namelen = htonl(strlen("bhyve"));
230
	sinfo.namelen = htonl(strlen("bhyve"));
227
	(void)stream_write(cfd, &sinfo, sizeof(sinfo));
231
	(void)stream_write(cfd, &sinfo, sizeof(sinfo));
228
	(void)stream_write(cfd, "bhyve", strlen("bhyve"));
232
	(void)stream_write(cfd, "bhyve", strlen("bhyve"));
Lines 265-271 Link Here
265
	int i;
269
	int i;
266
	uint32_t encoding;
270
	uint32_t encoding;
267
271
268
	assert((sizeof(enc_msg) - 1) == 3);
269
	(void)stream_read(cfd, ((void *)&enc_msg)+1, sizeof(enc_msg)-1);
272
	(void)stream_read(cfd, ((void *)&enc_msg)+1, sizeof(enc_msg)-1);
270
273
271
	for (i = 0; i < htons(enc_msg.numencs); i++) {
274
	for (i = 0; i < htons(enc_msg.numencs); i++) {
Lines 308-319 Link Here
308
	return (crcval);
311
	return (crcval);
309
}
312
}
310
313
314
static int
315
rfb_send_update_header(struct rfb_softc *rc, int cfd, int numrects)
316
{
317
	struct rfb_srvr_updt_msg supdt_msg;
311
318
319
	supdt_msg.type = 0;
320
	supdt_msg.pad = 0;
321
	supdt_msg.numrects = htons(numrects);
322
323
	return stream_write(cfd, &supdt_msg,
324
	    sizeof(struct rfb_srvr_updt_msg));
325
}
326
312
static int
327
static int
313
rfb_send_rect(struct rfb_softc *rc, int cfd, struct bhyvegc_image *gc,
328
rfb_send_rect(struct rfb_softc *rc, int cfd, struct bhyvegc_image *gc,
314
              int x, int y, int w, int h)
329
              int x, int y, int w, int h)
315
{
330
{
316
	struct rfb_srvr_updt_msg supdt_msg;
317
	struct rfb_srvr_rect_hdr srect_hdr;
331
	struct rfb_srvr_rect_hdr srect_hdr;
318
	unsigned long zlen;
332
	unsigned long zlen;
319
	ssize_t nwrite, total;
333
	ssize_t nwrite, total;
Lines 325-340 Link Here
325
	 * Send a single rectangle of the given x, y, w h dimensions.
339
	 * Send a single rectangle of the given x, y, w h dimensions.
326
	 */
340
	 */
327
341
328
	/* Number of rectangles: 1 */
329
	supdt_msg.type = 0;
330
	supdt_msg.pad = 0;
331
	supdt_msg.numrects = htons(1);
332
	nwrite = stream_write(cfd, &supdt_msg,
333
	                      sizeof(struct rfb_srvr_updt_msg));
334
	if (nwrite <= 0)
335
		return (nwrite);
336
337
338
	/* Rectangle header */
342
	/* Rectangle header */
339
	srect_hdr.x = htons(x);
343
	srect_hdr.x = htons(x);
340
	srect_hdr.y = htons(y);
344
	srect_hdr.y = htons(y);
Lines 479-485 Link Here
479
#define	PIXCELL_MASK	0x1F
483
#define	PIXCELL_MASK	0x1F
480
484
481
static int
485
static int
482
rfb_send_screen(struct rfb_softc *rc, int cfd, int all)
486
rfb_send_screen(struct rfb_softc *rc, int cfd)
483
{
487
{
484
	struct bhyvegc_image *gc_image;
488
	struct bhyvegc_image *gc_image;
485
	ssize_t nwrite;
489
	ssize_t nwrite;
Lines 493-501 Link Here
493
	uint32_t *crc_p, *orig_crc;
497
	uint32_t *crc_p, *orig_crc;
494
	int changes;
498
	int changes;
495
499
496
	console_refresh();
497
	gc_image = console_get_image();
498
499
	pthread_mutex_lock(&rc->mtx);
500
	pthread_mutex_lock(&rc->mtx);
500
	if (rc->sending) {
501
	if (rc->sending) {
501
		pthread_mutex_unlock(&rc->mtx);
502
		pthread_mutex_unlock(&rc->mtx);
Lines 504-513 Link Here
504
	rc->sending = 1;
505
	rc->sending = 1;
505
	pthread_mutex_unlock(&rc->mtx);
506
	pthread_mutex_unlock(&rc->mtx);
506
507
507
	retval = 0;
508
	retval = 1;
508
509
509
	if (all) {
510
	/* Updates require a preceding update request */
511
	if (!rc->pending)
512
		goto done;
513
514
	console_refresh();
515
	gc_image = console_get_image();
516
517
	/* Clear old CRC values when the size changes */
518
	if (rc->crc_width != gc_image->width ||
519
	    rc->crc_height != gc_image->height) {
520
		memset(rc->crc, 0, sizeof(uint32_t) *
521
		    howmany(RFB_MAX_WIDTH, PIX_PER_CELL) *
522
		    howmany(RFB_MAX_HEIGHT, PIX_PER_CELL));
523
		rc->crc_width = gc_image->width;
524
		rc->crc_height = gc_image->height;
525
	}
526
527
       /* A size update counts as an update in itself */
528
       if (rc->width != gc_image->width ||
529
           rc->height != gc_image->height) {
530
               rc->width = gc_image->width;
531
               rc->height = gc_image->height;
532
               if (rc->enc_resize_ok) {
533
                       rfb_send_resize_update_msg(rc, cfd);
534
                       rc->update_all = 1;
535
                       goto done;
536
               }
537
       }
538
539
	if (rc->update_all) {
510
		retval = rfb_send_all(rc, cfd, gc_image);
540
		retval = rfb_send_all(rc, cfd, gc_image);
541
		rc->update_all = 0;
511
		goto done;
542
		goto done;
512
	}
543
	}
513
544
Lines 516-526 Link Here
516
	 * has changed since the last scan.
547
	 * has changed since the last scan.
517
	 */
548
	 */
518
549
519
	/* Resolution changed */
520
521
	rc->crc_width = gc_image->width;
522
	rc->crc_height = gc_image->height;
523
524
	w = rc->crc_width;
550
	w = rc->crc_width;
525
	h = rc->crc_height;
551
	h = rc->crc_height;
526
	xcells = howmany(rc->crc_width, PIX_PER_CELL);
552
	xcells = howmany(rc->crc_width, PIX_PER_CELL);
Lines 580-591 Link Here
580
		}
606
		}
581
	}
607
	}
582
608
609
       /* We only send the update if there are changes */
610
	if (!changes) {
611
		goto done;
612
	}
613
	rc->pending = 0;
614
583
	/* If number of changes is > THRESH percent, send the whole screen */
615
	/* If number of changes is > THRESH percent, send the whole screen */
584
	if (((changes * 100) / (xcells * ycells)) >= RFB_SEND_ALL_THRESH) {
616
	if (((changes * 100) / (xcells * ycells)) >= RFB_SEND_ALL_THRESH) {
585
		retval = rfb_send_all(rc, cfd, gc_image);
617
		retval = rfb_send_all(rc, cfd, gc_image);
586
		goto done;
618
		goto done;
587
	}
619
	}
588
	
620
621
	rfb_send_update_header(rc, cfd, changes);
622
589
	/* Go through all cells, and send only changed ones */
623
	/* Go through all cells, and send only changed ones */
590
	crc_p = rc->crc_tmp;
624
	crc_p = rc->crc_tmp;
591
	for (y = 0; y < h; y += PIX_PER_CELL) {
625
	for (y = 0; y < h; y += PIX_PER_CELL) {
Lines 613-657 Link Here
613
			}
647
			}
614
		}
648
		}
615
	}
649
	}
616
	retval = 1;
617
650
618
done:
651
done:
619
	pthread_mutex_lock(&rc->mtx);
652
	pthread_mutex_lock(&rc->mtx);
620
	rc->sending = 0;
653
	rc->sending = 0;
621
	pthread_mutex_unlock(&rc->mtx);
654
	pthread_mutex_unlock(&rc->mtx);
622
	
655
623
	return (retval);
656
	return (retval);
624
}
657
}
625
658
626
659
627
static void
660
static void
628
rfb_recv_update_msg(struct rfb_softc *rc, int cfd, int discardonly)
661
rfb_recv_update_msg(struct rfb_softc *rc, int cfd)
629
{
662
{
630
	struct rfb_updt_msg updt_msg;
663
	struct rfb_updt_msg updt_msg;
631
	struct bhyvegc_image *gc_image;
632
664
633
	(void)stream_read(cfd, ((void *)&updt_msg) + 1 , sizeof(updt_msg) - 1);
665
	(void)stream_read(cfd, ((void *)&updt_msg) + 1 , sizeof(updt_msg) - 1);
634
666
635
	console_refresh();
667
	rc->pending = 1;
636
	gc_image = console_get_image();
668
	if (!updt_msg.incremental) {
637
669
		rc->update_all = 1;
638
	updt_msg.x = htons(updt_msg.x);
639
	updt_msg.y = htons(updt_msg.y);
640
	updt_msg.width = htons(updt_msg.width);
641
	updt_msg.height = htons(updt_msg.height);
642
643
	if (updt_msg.width != gc_image->width ||
644
	    updt_msg.height != gc_image->height) {
645
		rc->width = gc_image->width;
646
		rc->height = gc_image->height;
647
		if (rc->enc_resize_ok)
648
			rfb_send_resize_update_msg(rc, cfd);
649
	}
670
	}
650
651
	if (discardonly)
652
		return;
653
654
	rfb_send_screen(rc, cfd, 1);
655
}
671
}
656
672
657
static void
673
static void
Lines 731-737 Link Here
731
		if (tdiff > 40000) {
747
		if (tdiff > 40000) {
732
			prev_tv.tv_sec = tv.tv_sec;
748
			prev_tv.tv_sec = tv.tv_sec;
733
			prev_tv.tv_usec = tv.tv_usec;
749
			prev_tv.tv_usec = tv.tv_usec;
734
			if (rfb_send_screen(rc, cfd, 0) <= 0) {
750
			if (rfb_send_screen(rc, cfd) <= 0) {
735
				return (NULL);
751
				return (NULL);
736
			}
752
			}
737
		} else {
753
		} else {
Lines 758-764 Link Here
758
	DES_key_schedule ks;
774
	DES_key_schedule ks;
759
	int i;
775
	int i;
760
#endif
776
#endif
761
777
	uint8_t client_ver;
778
	uint8_t auth_type;
762
	pthread_t tid;
779
	pthread_t tid;
763
	uint32_t sres = 0;
780
	uint32_t sres = 0;
764
	int len;
781
	int len;
Lines 771-797 Link Here
771
788
772
	/* 1b. Read client version */
789
	/* 1b. Read client version */
773
	len = stream_read(cfd, buf, VERSION_LENGTH);
790
	len = stream_read(cfd, buf, VERSION_LENGTH);
791
	if (len == VERSION_LENGTH && !strncmp(vbuf, buf, VERSION_LENGTH - 2)) {
792
		client_ver = buf[VERSION_LENGTH - 2];
793
	}
794
	if (client_ver != '8' && client_ver != '7') {
795
		/* only recognize 3.3, 3.7 & 3.8. Others dflt to 3.3 */
796
		client_ver = '3';
797
	}
774
798
775
	/* 2a. Send security type */
799
	/* 2a. Send security type */
776
	buf[0] = 1;
800
	buf[0] = 1;
801
802
	/* In versions 3.7 & 3.8, it's 2-way handshake */
803
	/* For version 3.3, server says what the authentication type must be */
777
#ifndef NO_OPENSSL
804
#ifndef NO_OPENSSL
778
	if (rc->password) 
805
	if (rc->password) {
779
		buf[1] = SECURITY_TYPE_VNC_AUTH;
806
		auth_type = SECURITY_TYPE_VNC_AUTH;
780
	else
807
	} else {
781
		buf[1] = SECURITY_TYPE_NONE;
808
		auth_type = SECURITY_TYPE_NONE;
809
	}
782
#else
810
#else
783
	buf[1] = SECURITY_TYPE_NONE;
811
	auth_type = SECURITY_TYPE_NONE;
784
#endif
812
#endif
785
813
786
	stream_write(cfd, buf, 2);
814
	switch (client_ver) {
815
	case '7':
816
	case '8':
817
		buf[0] = 1;
818
		buf[1] = auth_type;
819
		stream_write(cfd, buf, 2);
787
820
788
	/* 2b. Read agreed security type */
821
		/* 2b. Read agreed security type */
789
	len = stream_read(cfd, buf, 1);
822
		len = stream_read(cfd, buf, 1);
823
		if (buf[0] != auth_type) {
824
			/* deny */
825
			sres = htonl(1);
826
			message = "Auth failed: authentication type mismatch";
827
			goto report_and_done;
828
		}
829
		break;
830
	case '3':
831
	default:
832
		be32enc(buf, auth_type);
833
		stream_write(cfd, buf, 4);
834
		break;
835
	}
790
836
791
	/* 2c. Do VNC authentication */
837
	/* 2c. Do VNC authentication */
792
	switch (buf[0]) {
838
	switch (auth_type) {
793
	case SECURITY_TYPE_NONE:
839
	case SECURITY_TYPE_NONE:
794
		sres = 0;
795
		break;
840
		break;
796
	case SECURITY_TYPE_VNC_AUTH:
841
	case SECURITY_TYPE_VNC_AUTH:
797
		/*
842
		/*
Lines 839-848 Link Here
839
		if (memcmp(crypt_expected, buf, AUTH_LENGTH) != 0) {
884
		if (memcmp(crypt_expected, buf, AUTH_LENGTH) != 0) {
840
			message = "Auth Failed: Invalid Password.";
885
			message = "Auth Failed: Invalid Password.";
841
			sres = htonl(1);
886
			sres = htonl(1);
842
		} else
887
		} else {
843
			sres = 0;
888
			sres = 0;
889
		}
844
#else
890
#else
845
		sres = 0;
891
		sres = htonl(1);
846
		WPRINTF(("Auth not supported, no OpenSSL in your system"));
892
		WPRINTF(("Auth not supported, no OpenSSL in your system"));
847
#endif
893
#endif
848
894
Lines 849-864 Link Here
849
		break;
895
		break;
850
	}
896
	}
851
897
852
	/* 2d. Write back a status */
898
	switch (client_ver) {
853
	stream_write(cfd, &sres, 4);
899
	case '7':
900
	case '8':
901
report_and_done:
902
		/* 2d. Write back a status */
903
		stream_write(cfd, &sres, 4);
854
904
855
	if (sres) {
905
		if (sres) {
856
		be32enc(buf, strlen(message));
906
			/* 3.7 does not want string explaining cause */
857
		stream_write(cfd, buf, 4);
907
			if (client_ver == '8') {
858
		stream_write(cfd, message, strlen(message));
908
				be32enc(buf, strlen(message));
859
		goto done;
909
				stream_write(cfd, buf, 4);
910
				stream_write(cfd, message, strlen(message));
911
			}
912
			goto done;
913
		}
914
		break;
915
	case '3':
916
	default:
917
		/* for VNC auth case send status */
918
		if (auth_type == SECURITY_TYPE_VNC_AUTH) {
919
			/* 2d. Write back a status */
920
			stream_write(cfd, &sres, 4);
921
		}
922
		if (sres) {
923
			goto done;
924
		}
925
		break;
860
	}
926
	}
861
862
	/* 3a. Read client shared-flag byte */
927
	/* 3a. Read client shared-flag byte */
863
	len = stream_read(cfd, buf, 1);
928
	len = stream_read(cfd, buf, 1);
864
929
Lines 870-877 Link Here
870
		assert(rc->zbuf != NULL);
935
		assert(rc->zbuf != NULL);
871
	}
936
	}
872
937
873
	rfb_send_screen(rc, cfd, 1);
874
875
	perror = pthread_create(&tid, NULL, rfb_wr_thr, rc);
938
	perror = pthread_create(&tid, NULL, rfb_wr_thr, rc);
876
	if (perror == 0)
939
	if (perror == 0)
877
		pthread_set_name_np(tid, "rfbout");
940
		pthread_set_name_np(tid, "rfbout");
Lines 892-898 Link Here
892
			rfb_recv_set_encodings_msg(rc, cfd);
955
			rfb_recv_set_encodings_msg(rc, cfd);
893
			break;
956
			break;
894
		case 3:
957
		case 3:
895
			rfb_recv_update_msg(rc, cfd, 1);
958
			rfb_recv_update_msg(rc, cfd);
896
			break;
959
			break;
897
		case 4:
960
		case 4:
898
			rfb_recv_key_msg(rc, cfd);
961
			rfb_recv_key_msg(rc, cfd);
Lines 974-979 Link Here
974
	struct addrinfo *ai = NULL;
1037
	struct addrinfo *ai = NULL;
975
	struct addrinfo hints;
1038
	struct addrinfo hints;
976
	int on = 1;
1039
	int on = 1;
1040
	int cnt;
977
#ifndef WITHOUT_CAPSICUM
1041
#ifndef WITHOUT_CAPSICUM
978
	cap_rights_t rights;
1042
	cap_rights_t rights;
979
#endif
1043
#endif
Lines 980-989 Link Here
980
1044
981
	rc = calloc(1, sizeof(struct rfb_softc));
1045
	rc = calloc(1, sizeof(struct rfb_softc));
982
1046
983
	rc->crc = calloc(howmany(RFB_MAX_WIDTH * RFB_MAX_HEIGHT, 32),
1047
	cnt = howmany(RFB_MAX_WIDTH, PIX_PER_CELL) *
984
	                 sizeof(uint32_t));
1048
	    howmany(RFB_MAX_HEIGHT, PIX_PER_CELL);
985
	rc->crc_tmp = calloc(howmany(RFB_MAX_WIDTH * RFB_MAX_HEIGHT, 32),
1049
	rc->crc = calloc(cnt, sizeof(uint32_t));
986
	                     sizeof(uint32_t));
1050
	rc->crc_tmp = calloc(cnt, sizeof(uint32_t));
987
	rc->crc_width = RFB_MAX_WIDTH;
1051
	rc->crc_width = RFB_MAX_WIDTH;
988
	rc->crc_height = RFB_MAX_HEIGHT;
1052
	rc->crc_height = RFB_MAX_HEIGHT;
989
	rc->sfd = -1;
1053
	rc->sfd = -1;

Return to bug 250795