1 /*
2    Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
3    All rights reserved.
4 
5 This file is part of x11vnc.
6 
7 x11vnc is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or (at
10 your option) any later version.
11 
12 x11vnc is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with x11vnc; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
20 or see <http://www.gnu.org/licenses/>.
21 
22 In addition, as a special exception, Karl J. Runge
23 gives permission to link the code of its release of x11vnc with the
24 OpenSSL project's "OpenSSL" library (or with modified versions of it
25 that use the same license as the "OpenSSL" library), and distribute
26 the linked executables.  You must obey the GNU General Public License
27 in all respects for all of the code used other than "OpenSSL".  If you
28 modify this file, you may extend this exception to your version of the
29 file, but you are not obligated to do so.  If you do not wish to do
30 so, delete this exception statement from your version.
31 */
32 
33 /* -- sslhelper.c -- */
34 
35 #include "x11vnc.h"
36 #include "inet.h"
37 #include "cleanup.h"
38 #include "screen.h"
39 #include "scan.h"
40 #include "connections.h"
41 #include "sslcmds.h"
42 #include "unixpw.h"
43 #include "user.h"
44 
45 #define OPENSSL_INETD   1
46 #define OPENSSL_VNC     2
47 #define OPENSSL_VNC6    3
48 #define OPENSSL_HTTPS   4
49 #define OPENSSL_HTTPS6  5
50 #define OPENSSL_REVERSE 6
51 
52 #define DO_DH 0
53 
54 #if LIBVNCSERVER_HAVE_FORK
55 #if LIBVNCSERVER_HAVE_SYS_WAIT_H && HAVE_WAITPID
56 #define FORK_OK
57 #endif
58 #endif
59 
60 int openssl_sock = -1;
61 int openssl_sock6 = -1;
62 int openssl_port_num = 0;
63 int https_sock = -1;
64 int https_sock6 = -1;
65 pid_t openssl_last_helper_pid = 0;
66 char *openssl_last_ip = NULL;
67 
68 static char *certret = NULL;
69 static int certret_fd = -1;
70 static mode_t omode;
71 char *certret_str = NULL;
72 
73 static char *dhret = NULL;
74 static int dhret_fd = -1;
75 char *dhret_str = NULL;
76 char *new_dh_params = NULL;
77 
78 void raw_xfer(int csock, int s_in, int s_out);
79 
80 /* openssl(1) pem related functions: */
81 char *get_saved_pem(char *string, int create);
82 char *find_openssl_bin(void);
83 char *get_ssl_verify_file(char *str_in);
84 char *create_tmp_pem(char *path, int prompt);
85 
86 static char *get_input(char *tag, char **in);
87 
get_saved_pem(char * save,int create)88 char *get_saved_pem(char *save, int create) {
89 	char *s = NULL, *path, *cdir, *tmp;
90 	int prompt = 0, len;
91 	struct stat sbuf;
92 
93 	if (! save) {
94 		rfbLog("get_saved_pem: save string is null.\n");
95 		clean_up_exit(1);
96 	}
97 
98 	if (strstr(save, "SAVE_PROMPT") == save) {
99 		prompt = 1;
100 		s = save + strlen("SAVE_PROMPT");
101 	} else if (strstr(save, "SAVE_NOPROMPT") == save) {
102 		set_env("GENCERT_NOPROMPT", "1");
103 		s = save + strlen("SAVE_NOPROMPT");
104 	} else if (strstr(save, "SAVE") == save) {
105 		s = save + strlen("SAVE");
106 	} else {
107 		rfbLog("get_saved_pem: invalid save string: %s\n", save);
108 		clean_up_exit(1);
109 	}
110 	if (strchr(s, '/')) {
111 		rfbLog("get_saved_pem: invalid save string: %s\n", s);
112 		clean_up_exit(1);
113 	}
114 
115 
116 	cdir = get_Cert_dir(NULL, &tmp);
117 	if (! cdir || ! tmp) {
118 		rfbLog("get_saved_pem: could not find Cert dir.\n");
119 		clean_up_exit(1);
120 	}
121 
122 	len = strlen(cdir) + strlen("/server.pem") + strlen(s) + 1;
123 
124 	path = (char *) malloc(len);
125 	sprintf(path, "%s/server%s.pem", cdir, s);
126 
127 	if (stat(path, &sbuf) != 0) {
128 		char *new_name = NULL;
129 		if (create) {
130 			if (inetd || opts_bg) {
131 				set_env("GENCERT_NOPROMPT", "1");
132 			}
133 			new_name = create_tmp_pem(path, prompt);
134 			if (!getenv("X11VNC_SSL_NO_PASSPHRASE") && !inetd && !opts_bg) {
135 				sslEncKey(new_name, 0);
136 			}
137 		}
138 		return new_name;
139 	}
140 
141 	if (! quiet) {
142 		char line[1024];
143 		int on = 0;
144 		FILE *in = fopen(path, "r");
145 		if (in != NULL) {
146 			rfbLog("\n");
147 			rfbLog("Using SSL Certificate:\n");
148 			fprintf(stderr, "\n");
149 			while (fgets(line, 1024, in) != NULL) {
150 				if (strstr(line, "BEGIN CERTIFICATE")) {
151 					on = 1;
152 				}
153 				if (on) {
154 					fprintf(stderr, "%s", line);
155 				}
156 				if (strstr(line, "END CERTIFICATE")) {
157 					on = 0;
158 				}
159 				if (strstr(line, "PRIVATE KEY")) {
160 					on = 0;
161 				}
162 			}
163 			fprintf(stderr, "\n");
164 			fclose(in);
165 		}
166 	}
167 	return strdup(path);
168 }
169 
get_input(char * tag,char ** in)170 static char *get_input(char *tag, char **in) {
171 	char line[1024], *str;
172 
173 	if (! tag || ! in || ! *in) {
174 		return NULL;
175 	}
176 
177 	fprintf(stderr, "%s:\n     [%s] ", tag, *in);
178 	if (fgets(line, 1024, stdin) == NULL) {
179 		rfbLog("could not read stdin!\n");
180 		rfbLogPerror("fgets");
181 		clean_up_exit(1);
182 	}
183 	if ((str = strrchr(line, '\n')) != NULL) {
184 		*str = '\0';
185 	}
186 	str = lblanks(line);
187 	if (!strcmp(str, "")) {
188 		return *in;
189 	} else {
190 		return strdup(line);
191 	}
192 }
193 
find_openssl_bin(void)194 char *find_openssl_bin(void) {
195 	char *path, *exe, *p, *gp;
196 	struct stat sbuf;
197 	int found_openssl = 0;
198 	char extra[] = ":/usr/bin:/bin:/usr/sbin:/usr/local/bin"
199 	    ":/usr/local/sbin:/usr/sfw/bin";
200 
201 	gp = getenv("PATH");
202 	if (! gp) {
203 		fprintf(stderr, "could not find openssl(1) program in PATH. (null)\n");
204 		return NULL;
205 	}
206 
207 	path = (char *) malloc(strlen(gp) + strlen(extra) + 1);
208 	strcpy(path, gp);
209 	strcat(path, extra);
210 
211 	/* find openssl binary: */
212 	exe = (char *) malloc(strlen(path) + strlen("/openssl") + 1);
213 	p = strtok(path, ":");
214 
215 	while (p) {
216 		sprintf(exe, "%s/openssl", p);
217 		if (stat(exe, &sbuf) == 0) {
218 			if (! S_ISDIR(sbuf.st_mode)) {
219 				found_openssl = 1;
220 				break;
221 			}
222 		}
223 		p = strtok(NULL, ":");
224 	}
225 	free(path);
226 
227 	if (! found_openssl) {
228 		fprintf(stderr, "could not find openssl(1) program in PATH.\n");
229 		fprintf(stderr, "PATH=%s\n", gp);
230 		fprintf(stderr, "(also checked: %s)\n", extra);
231 		return NULL;
232 	}
233 	return exe;
234 }
235 
236 /* uses /usr/bin/openssl to create a tmp cert */
237 
create_tmp_pem(char * pathin,int prompt)238 char *create_tmp_pem(char *pathin, int prompt) {
239 	pid_t pid, pidw;
240 	FILE *in, *out;
241 	char cnf[] = "/tmp/x11vnc-cnf.XXXXXX";
242 	char pem[] = "/tmp/x11vnc-pem.XXXXXX";
243 	char str[8*1024], line[1024], *exe;
244 	int cnf_fd, pem_fd, status, show_cert = 1;
245 	char *days;
246 	char *C, *L, *OU, *O, *CN, *EM;
247 	char tmpl[] =
248 "[ req ]\n"
249 "prompt = no\n"
250 "default_bits = 2048\n"
251 "encrypt_key = yes\n"
252 "distinguished_name = req_dn\n"
253 "x509_extensions = cert_type\n"
254 "\n"
255 "[ req_dn ]\n"
256 "countryName=%s\n"
257 "localityName=%s\n"
258 "organizationalUnitName=%s\n"
259 "organizationName=%s\n"
260 "commonName=%s\n"
261 "emailAddress=%s\n"
262 "\n"
263 "[ cert_type ]\n"
264 "nsCertType = server\n"
265 ;
266 
267 	C = strdup("AU");
268 	L = strdup(UT.sysname ? UT.sysname : "unknown-os");
269 	snprintf(line, sizeof line, "%s-%f", UT.nodename ? UT.nodename :
270 	    "unknown-node", dnow());
271 	line[1024-1] = '\0';
272 
273 	OU = strdup(line);
274 	O = strdup("x11vnc");
275 	if (pathin) {
276 		snprintf(line, sizeof line, "x11vnc-SELF-SIGNED-CERT-%d", getpid());
277 	} else {
278 		snprintf(line, sizeof line, "x11vnc-SELF-SIGNED-TEMPORARY-CERT-%d",
279 		    getpid());
280 	}
281 	line[1024-1] = '\0';
282 	CN = strdup(line);
283 	EM = strdup("x11vnc@server.nowhere");
284 
285 	/* ssl */
286 	if (no_external_cmds || !cmd_ok("ssl")) {
287 		rfbLog("create_tmp_pem: cannot run external commands.\n");
288 		return NULL;
289 	}
290 
291 	rfbLog("\n");
292 	if (pathin) {
293 		rfbLog("Creating a self-signed PEM certificate...\n");
294 	} else {
295 		rfbLog("Creating a temporary, self-signed PEM certificate...\n");
296 	}
297 
298 	rfbLog("\n");
299 	rfbLog("This will NOT prevent Man-In-The-Middle attacks UNLESS you\n");
300 	rfbLog("get the certificate information to the VNC viewers SSL\n");
301 	rfbLog("tunnel configuration or you take the extra steps to sign it\n");
302 	rfbLog("with a CA key. However, it will prevent passive network\n");
303 	rfbLog("sniffing.\n");
304 	rfbLog("\n");
305 	rfbLog("The cert inside -----BEGIN CERTIFICATE-----\n");
306 	rfbLog("                           ....\n");
307 	rfbLog("                -----END CERTIFICATE-----\n");
308 	rfbLog("printed below may be used on the VNC viewer-side to\n");
309 	rfbLog("authenticate this server for this session.  See the -ssl\n");
310 	rfbLog("help output and the FAQ for how to create a permanent\n");
311 	rfbLog("server certificate.\n");
312 	rfbLog("\n");
313 
314 	exe = find_openssl_bin();
315 	if (! exe) {
316 		return NULL;
317 	}
318 
319 	/* create template file with our made up stuff: */
320 	if (prompt) {
321 		fprintf(stderr, "\nReply to the following prompts to set"
322 		    " your Certificate parameters.\n");
323 		fprintf(stderr, "(press Enter to accept the default in [...], "
324 		    "or type in the value you want)\n\n");
325 		C = get_input("CountryName", &C);
326 		L = get_input("LocalityName", &L);
327 		OU = get_input("OrganizationalUnitName", &OU);
328 		O = get_input("OrganizationalName", &O);
329 		CN = get_input("CommonName", &CN);
330 		EM = get_input("EmailAddress", &EM);
331 	}
332 	sprintf(str, tmpl, C, L, OU, O, CN, EM);
333 
334 	cnf_fd = mkstemp(cnf);
335 	if (cnf_fd < 0) {
336 		return NULL;
337 	}
338 	pem_fd = mkstemp(pem);
339 	if (pem_fd < 0) {
340 		close(cnf_fd);
341 		return NULL;
342 	}
343 
344 	close(pem_fd);
345 
346 	write(cnf_fd, str, strlen(str));
347 	close(cnf_fd);
348 
349 	if (pathin) {
350 		days = "365";
351 	} else {
352 		days = "30";
353 	}
354 
355 #ifndef FORK_OK
356 	rfbLog("not compiled with fork(2)\n");
357 	clean_up_exit(1);
358 #else
359 	/* make RSA key */
360 	pid = fork();
361 	if (pid < 0) {
362 		return NULL;
363 	} else if (pid == 0) {
364 		int i;
365 		for (i=0; i<256; i++) {
366 			close(i);
367 		}
368 		execlp(exe, exe, "req", "-new", "-x509", "-nodes",
369 		    "-days", days, "-config", cnf, "-out", pem,
370 		    "-keyout", pem, (char *)0);
371 		exit(1);
372 	}
373 	pidw = waitpid(pid, &status, 0);
374 	if (pidw != pid) {
375 		return NULL;
376 	}
377 	if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
378 		;
379 	} else {
380 		return NULL;
381 	}
382 
383 #if DO_DH
384 	/* make DH parameters */
385 	pid = fork();
386 	if (pid < 0) {
387 		return NULL;
388 	} else if (pid == 0) {
389 		int i;
390 		for (i=0; i<256; i++) {
391 			close(i);
392 		}
393 		/* rather slow at 1024 */
394 		execlp(exe, exe, "dhparam", "-out", cnf, "512", (char *)0);
395 		exit(1);
396 	}
397 	pidw = waitpid(pid, &status, 0);
398 	if (pidw != pid) {
399 		return NULL;
400 	}
401 	if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
402 		;
403 	} else {
404 		return NULL;
405 	}
406 
407 	/* append result: */
408 	in = fopen(cnf, "r");
409 	if (in == NULL) {
410 		return NULL;
411 	}
412 	out = fopen(pem, "a");
413 	if (out == NULL) {
414 		fclose(in);
415 		return NULL;
416 	}
417 	while (fgets(line, 1024, in) != NULL) {
418 		fprintf(out, "%s", line);
419 	}
420 	fclose(in);
421 	fclose(out);
422 #endif
423 
424 #endif	/* FORK_OK */
425 
426 	unlink(cnf);
427 	free(exe);
428 
429 	if (pathin != NULL) {
430 		char *q, *pathcrt = strdup(pathin);
431 		FILE *crt = NULL;
432 		int on = 0;
433 
434 		q = strrchr(pathcrt, '/');
435 		if (q) {
436 			q = strstr(q, ".pem");
437 			if (q) {
438 				*(q+1) = 'c';
439 				*(q+2) = 'r';
440 				*(q+3) = 't';
441 				crt = fopen(pathcrt, "w");
442 			}
443 		}
444 		if (crt == NULL) {
445 			rfbLog("could not open: %s\n", pathcrt);
446 			rfbLogPerror("fopen");
447 			return NULL;
448 		}
449 
450 		out = fopen(pathin, "w");
451 		chmod(pathin,  0600);
452 		if (out == NULL) {
453 			rfbLog("could not open: %s\n", pathin);
454 			rfbLogPerror("fopen");
455 			fclose(crt);
456 			return NULL;
457 		}
458 
459 		in = fopen(pem, "r");
460 		if (in == NULL) {
461 			rfbLog("could not open: %s\n", pem);
462 			rfbLogPerror("fopen");
463 			fclose(out);
464 			fclose(crt);
465 			unlink(pathin);
466 			unlink(pathcrt);
467 			return NULL;
468 		}
469 		while (fgets(line, 1024, in) != NULL) {
470 			if (strstr(line, "BEGIN CERTIFICATE")) {
471 				on = 1;
472 			}
473 			fprintf(out, "%s", line);
474 			if (on) {
475 				fprintf(crt, "%s", line);
476 				if (!quiet) {
477 					fprintf(stderr, "%s", line);
478 				}
479 			}
480 			if (strstr(line, "END CERTIFICATE")) {
481 				on = 0;
482 			}
483 			if (strstr(line, "PRIVATE KEY")) {
484 				on = 0;
485 			}
486 		}
487 		fclose(in);
488 		fclose(out);
489 		fclose(crt);
490 	}
491 
492 	if (show_cert) {
493 		exe = find_openssl_bin();
494 		if (!exe) {
495 			exe = strdup("openssl");
496 		}
497 		if (strlen(pem) + strlen(exe) < 4000) {
498 			char cmd[5000];
499 			if (inetd) {
500 				sprintf(cmd, "%s x509 -text -in '%s' 1>&2", exe, pem);
501 			} else {
502 				sprintf(cmd, "%s x509 -text -in '%s'", exe, pem);
503 			}
504 			fprintf(stderr, "\n");
505 			system(cmd);
506 			fprintf(stderr, "\n");
507 		}
508 		free(exe);
509 	}
510 
511 	if (pathin) {
512 		unlink(pem);
513 		return strdup(pathin);
514 	} else {
515 		return strdup(pem);
516 	}
517 }
518 
appendfile(FILE * out,char * infile)519 static int appendfile(FILE *out, char *infile) {
520 	char line[1024];
521 	FILE *in;
522 
523 	if (! infile) {
524 		rfbLog("appendfile: null infile.\n");
525 		return 0;
526 	}
527 	if (! out) {
528 		rfbLog("appendfile: null out handle.\n");
529 		return 0;
530 	}
531 
532 	in = fopen(infile, "r");
533 
534 	if (in == NULL) {
535 		rfbLog("appendfile: %s\n", infile);
536 		rfbLogPerror("fopen");
537 		return 0;
538 	}
539 
540 	while (fgets(line, 1024, in) != NULL) {
541 		fprintf(out, "%s", line);
542 	}
543 	fclose(in);
544 	return 1;
545 }
546 
get_ssl_verify_file(char * str_in)547 char *get_ssl_verify_file(char *str_in) {
548 	char *p, *str, *cdir, *tmp;
549 	char *tfile, *tfile2;
550 	FILE *file;
551 	struct stat sbuf;
552 	int count = 0, fd;
553 
554 	if (! str_in) {
555 		rfbLog("get_ssl_verify_file: no filename\n");
556 		exit(1);
557 	}
558 
559 	if (stat(str_in, &sbuf) == 0) {
560 		/* assume he knows what he is doing. */
561 		return str_in;
562 	}
563 
564 	cdir = get_Cert_dir(NULL, &tmp);
565 	if (! cdir || ! tmp) {
566 		rfbLog("get_ssl_verify_file: invalid cert-dir.\n");
567 		exit(1);
568 	}
569 
570 	tfile  = (char *) malloc(strlen(tmp) + 1024);
571 	tfile2 = (char *) malloc(strlen(tmp) + 1024);
572 
573 	sprintf(tfile, "%s/sslverify-tmp-load-%d.crts.XXXXXX", tmp, getpid());
574 
575 	fd = mkstemp(tfile);
576 	if (fd < 0) {
577 		rfbLog("get_ssl_verify_file: %s\n", tfile);
578 		rfbLogPerror("mkstemp");
579 		exit(1);
580 	}
581 	close(fd);
582 
583 	file = fopen(tfile, "w");
584 	chmod(tfile, 0600);
585 	if (file == NULL) {
586 		rfbLog("get_ssl_verify_file: %s\n", tfile);
587 		rfbLogPerror("fopen");
588 		exit(1);
589 	}
590 
591 	str = strdup(str_in);
592 	p = strtok(str, ",");
593 
594 	while (p) {
595 		if (!strcmp(p, "CA")) {
596 			sprintf(tfile2, "%s/CA/cacert.pem", cdir);
597 			if (! appendfile(file, tfile2)) {
598 				unlink(tfile);
599 				exit(1);
600 			}
601 			rfbLog("sslverify: loaded %s\n", tfile2);
602 			count++;
603 
604 		} else if (!strcmp(p, "clients")) {
605 			DIR *dir;
606 			struct dirent *dp;
607 
608 			sprintf(tfile2, "%s/clients", cdir);
609 			dir = opendir(tfile2);
610 			if (! dir) {
611 				rfbLog("get_ssl_verify_file: %s\n", tfile2);
612 				rfbLogPerror("opendir");
613 				unlink(tfile);
614 				exit(1);
615 			}
616 			while ( (dp = readdir(dir)) != NULL) {
617 				char *n = dp->d_name;
618 				char *q = strstr(n, ".crt");
619 
620 				if (! q || strlen(q) != strlen(".crt")) {
621 					continue;
622 				}
623 				if (strlen(n) > 512) {
624 					continue;
625 				}
626 
627 				sprintf(tfile2, "%s/clients/%s", cdir, n);
628 				if (! appendfile(file, tfile2)) {
629 					unlink(tfile);
630 					exit(1);
631 				}
632 				rfbLog("sslverify: loaded %s\n",
633 				    tfile2);
634 				count++;
635 			}
636 			closedir(dir);
637 
638 		} else {
639 			if (strlen(p) > 512) {
640 				unlink(tfile);
641 				exit(1);
642 			}
643 			sprintf(tfile2, "%s/clients/%s.crt", cdir, p);
644 			if (stat(tfile2, &sbuf) != 0) {
645 				sprintf(tfile2, "%s/clients/%s", cdir, p);
646 			}
647 			if (! appendfile(file, tfile2)) {
648 				unlink(tfile);
649 				exit(1);
650 			}
651 			rfbLog("sslverify: loaded %s\n", tfile2);
652 			count++;
653 		}
654 		p = strtok(NULL, ",");
655 	}
656 	fclose(file);
657 	free(tfile2);
658 	free(str);
659 
660 	rfbLog("sslverify: using %d client certs in\n", count);
661 	rfbLog("sslverify: %s\n", tfile);
662 
663 	return tfile;
664 }
665 
666 int openssl_present(void);
667 void openssl_init(int isclient);
668 void openssl_port(int restart);
669 void https_port(int restart);
670 void check_openssl(void);
671 void check_https(void);
672 void ssl_helper_pid(pid_t pid, int sock);
673 void accept_openssl(int mode, int presock);
674 
675 static void lose_ram(void);
676 #define ABSIZE 16384
677 
678 static int vencrypt_selected = 0;
679 static int anontls_selected = 0;
680 
681 /* to test no openssl libssl */
682 #if 0
683 #undef LIBVNCSERVER_HAVE_LIBSSL
684 #define LIBVNCSERVER_HAVE_LIBSSL 0
685 #undef  HAVE_LIBSSL
686 #define HAVE_LIBSSL 0
687 #endif
688 
689 #if !LIBVNCSERVER_HAVE_LIBSSL && !HAVE_LIBSSL
690 
badnews(char * name)691 static void badnews(char *name) {
692 	use_openssl = 0;
693 	use_stunnel = 0;
694 	rfbLog("** %s: not compiled with libssl OpenSSL support **\n", name ? name : "???");
695 	clean_up_exit(1);
696 }
697 
openssl_present(void)698 int openssl_present(void) {return 0;}
openssl_init(int isclient)699 void openssl_init(int isclient) {badnews("openssl_init");}
700 
701 #define SSL_ERROR_NONE 0
702 
ssl_init(int s_in,int s_out,int skip_vnc_tls,double last_https)703 static int ssl_init(int s_in, int s_out, int skip_vnc_tls, double last_https) {
704 	if (enc_str != NULL) {
705 		return 1;
706 	}
707 	badnews("ssl_init");
708 	return 0;
709 }
710 
ssl_xfer(int csock,int s_in,int s_out,int is_https)711 static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
712 	if (enc_str != NULL && !strcmp(enc_str, "none")) {
713 		usleep(250*1000);
714 		rfbLog("doing '-enc none' raw transfer (no encryption)\n");
715 		raw_xfer(csock, s_in, s_out);
716 	} else {
717 		badnews("ssl_xfer");
718 	}
719 }
720 
721 #else 	/* LIBVNCSERVER_HAVE_LIBSSL or HAVE_LIBSSL */
722 
723 /*
724  * This is because on older systems both zlib.h and ssl.h define
725  * 'free_func' nothing we do below (currently) induces an external
726  * dependency on 'free_func'.
727  */
728 #define free_func my_jolly_little_free_func
729 
730 #include <openssl/ssl.h>
731 #include <openssl/err.h>
732 #include <openssl/rand.h>
733 
734 static SSL_CTX *ctx = NULL;
735 static RSA *rsa_512 = NULL;
736 static RSA *rsa_1024 = NULL;
737 static SSL *ssl = NULL;
738 static X509_STORE *revocation_store = NULL;
739 
740 
741 static void init_prng(void);
742 static void sslerrexit(void);
743 static int  ssl_init(int s_in, int s_out, int skip_vnc_tls, double last_https);
744 static void ssl_xfer(int csock, int s_in, int s_out, int is_https);
745 
746 #ifndef FORK_OK
openssl_init(int isclient)747 void openssl_init(int isclient) {
748 	rfbLog("openssl_init: fork is not supported. cannot create"
749 	    " ssl helper process.\n");
750 	clean_up_exit(1);
751 }
openssl_present(void)752 int openssl_present(void) {return 0;}
753 
754 #else
755 
openssl_present(void)756 int openssl_present(void) {return 1;}
757 
sslerrexit(void)758 static void sslerrexit(void) {
759 	unsigned long err = ERR_get_error();
760 
761 	if (err) {
762 		char str[256];
763 		ERR_error_string(err, str);
764 		fprintf(stderr, "ssl error: %s\n", str);
765 	}
766 	clean_up_exit(1);
767 }
768 
pem_passwd_callback(char * buf,int size,int rwflag,void * userdata)769 static int pem_passwd_callback(char *buf, int size, int rwflag,
770     void *userdata) {
771 	char *q, line[1024];
772 
773 	if (! buf) {
774 		exit(1);
775 	}
776 
777 	fprintf(stderr, "\nA passphrase is needed to unlock an OpenSSL "
778 	    "private key (PEM file).\n");
779 	fprintf(stderr, "Enter passphrase> ");
780 	system("stty -echo");
781 	if(fgets(line, 1024, stdin) == NULL) {
782 		fprintf(stdout, "\n");
783 		system("stty echo");
784 		exit(1);
785 	}
786 	system("stty echo");
787 	fprintf(stdout, "\n\n");
788 	q = strrchr(line, '\n');
789 	if (q) {
790 		*q = '\0';
791 	}
792 	line[1024 - 1] = '\0';
793 	strncpy(buf, line, size);
794 	buf[size - 1] = '\0';
795 
796 	if (0) rwflag = 0;	/* compiler warning. */
797 	if (0) userdata = 0;	/* compiler warning. */
798 
799 	return strlen(buf);
800 }
801 
802 /* based on mod_ssl */
crl_callback(X509_STORE_CTX * callback_ctx)803 static int crl_callback(X509_STORE_CTX *callback_ctx) {
804 	const ASN1_INTEGER *revoked_serial;
805 	X509_STORE_CTX *store_ctx;
806 #if OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
807 	X509_OBJECT *obj;
808 #else
809 	X509_OBJECT obj;
810 #endif
811 	X509_NAME *subject;
812 	X509_NAME *issuer;
813 	X509 *xs;
814 	X509_CRL *crl;
815 	X509_REVOKED *revoked;
816 	EVP_PKEY *pubkey;
817 	long serial;
818 	BIO *bio;
819 	int i, n, rc;
820 	char *cp, *cp2;
821 	ASN1_TIME *t;
822 
823 	/* Determine certificate ingredients in advance */
824 	xs      = X509_STORE_CTX_get_current_cert(callback_ctx);
825 	subject = X509_get_subject_name(xs);
826 	issuer  = X509_get_issuer_name(xs);
827 
828 	/* Try to retrieve a CRL corresponding to the _subject_ of
829 	* the current certificate in order to verify it's integrity. */
830 	store_ctx = X509_STORE_CTX_new();
831 	X509_STORE_CTX_init(store_ctx, revocation_store, NULL, NULL);
832 #if OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
833 	obj = X509_OBJECT_new();
834 	rc=X509_STORE_get_by_subject(store_ctx, X509_LU_CRL, subject, obj);
835 	crl = X509_OBJECT_get0_X509_CRL(obj);
836 #else
837 	memset((char *)&obj, 0, sizeof(obj));
838 	rc=X509_STORE_get_by_subject(store_ctx, X509_LU_CRL, subject, &obj);
839 	crl=obj.data.crl;
840 #endif
841 	X509_STORE_CTX_cleanup(store_ctx);
842 	X509_STORE_CTX_free(store_ctx);
843 
844 	if(rc>0 && crl) {
845 		/* Log information about CRL
846 		 * (A little bit complicated because of ASN.1 and BIOs...) */
847 		bio=BIO_new(BIO_s_mem());
848 		BIO_printf(bio, "lastUpdate: ");
849 		ASN1_UTCTIME_print(bio, X509_CRL_get_lastUpdate(crl));
850 		BIO_printf(bio, ", nextUpdate: ");
851 		ASN1_UTCTIME_print(bio, X509_CRL_get_nextUpdate(crl));
852 		n=BIO_pending(bio);
853 		cp=malloc(n+1);
854 		n=BIO_read(bio, cp, n);
855 		cp[n]='\0';
856 		BIO_free(bio);
857 		cp2=X509_NAME_oneline(subject, NULL, 0);
858 		rfbLog("CA CRL: Issuer: %s, %s\n", cp2, cp);
859 		OPENSSL_free(cp2);
860 		free(cp);
861 
862 		/* Verify the signature on this CRL */
863 		pubkey=X509_get_pubkey(xs);
864 		if(X509_CRL_verify(crl, pubkey)<=0) {
865 			rfbLog("Invalid signature on CRL\n");
866 			X509_STORE_CTX_set_error(callback_ctx,
867 				X509_V_ERR_CRL_SIGNATURE_FAILURE);
868 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
869 			X509_OBJECT_free(obj);
870 #else
871 			X509_OBJECT_free_contents(&obj);
872 #endif
873 			if(pubkey)
874 				EVP_PKEY_free(pubkey);
875 			return 0; /* Reject connection */
876 		}
877 		if(pubkey)
878 			EVP_PKEY_free(pubkey);
879 
880 		/* Check date of CRL to make sure it's not expired */
881 		t=X509_CRL_get_nextUpdate(crl);
882 		if(!t) {
883 			rfbLog("Found CRL has invalid nextUpdate field\n");
884 			X509_STORE_CTX_set_error(callback_ctx,
885 				X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
886 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
887 			X509_OBJECT_free(obj);
888 #else
889 			X509_OBJECT_free_contents(&obj);
890 #endif
891 			return 0; /* Reject connection */
892 		}
893 		if(X509_cmp_current_time(t)<0) {
894 			rfbLog("Found CRL is expired - "
895 				"revoking all certificates until you get updated CRL\n");
896 			X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CRL_HAS_EXPIRED);
897 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
898 			X509_OBJECT_free(obj);
899 #else
900 			X509_OBJECT_free_contents(&obj);
901 #endif
902 			return 0; /* Reject connection */
903 		}
904 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
905 			X509_OBJECT_free(obj);
906 #else
907 			X509_OBJECT_free_contents(&obj);
908 #endif
909 	}
910 
911 	/* Try to retrieve a CRL corresponding to the _issuer_ of
912 	 * the current certificate in order to check for revocation. */
913 	store_ctx = X509_STORE_CTX_new();
914 	X509_STORE_CTX_init(store_ctx, revocation_store, NULL, NULL);
915 #if OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
916 	obj = X509_OBJECT_new();
917 	rc=X509_STORE_get_by_subject(store_ctx, X509_LU_CRL, issuer, obj);
918 	crl = X509_OBJECT_get0_X509_CRL(obj);
919 #else
920 	memset((char *)&obj, 0, sizeof(obj));
921 	rc=X509_STORE_get_by_subject(store_ctx, X509_LU_CRL, issuer, &obj);
922 	crl=obj.data.crl;
923 #endif
924 	X509_STORE_CTX_cleanup(store_ctx);
925 	X509_STORE_CTX_free(store_ctx);
926 
927 	if(rc>0 && crl) {
928 		/* Check if the current certificate is revoked by this CRL */
929 		n=sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
930 		for(i=0; i<n; i++) {
931 			revoked=sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
932 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
933 			revoked_serial = X509_REVOKED_get0_serialNumber(revoked);
934 #else
935 			revoked_serial = revoked->serialNumber;
936 #endif
937 			if(ASN1_INTEGER_cmp(revoked_serial,
938 					X509_get_serialNumber(xs)) == 0) {
939 				serial=ASN1_INTEGER_get(revoked_serial);
940 				cp=X509_NAME_oneline(issuer, NULL, 0);
941 				rfbLog("Certificate with serial %ld (0x%lX) "
942 					"revoked per CRL from issuer %s\n", serial, serial, cp);
943 				OPENSSL_free(cp);
944 				X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CERT_REVOKED);
945 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
946 				X509_OBJECT_free(obj);
947 #else
948 				X509_OBJECT_free_contents(&obj);
949 #endif
950 				return 0; /* Reject connection */
951 			}
952 		}
953 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
954 			X509_OBJECT_free(obj);
955 #else
956 			X509_OBJECT_free_contents(&obj);
957 #endif
958 	}
959 
960 	return 1; /* Accept connection */
961 }
962 
verify_callback(int ok,X509_STORE_CTX * callback_ctx)963 static int verify_callback(int ok, X509_STORE_CTX *callback_ctx) {
964 	if (!ssl_verify) {
965 		rfbLog("CRL_check: skipped.\n");
966 		return ok;
967 	}
968 	if (!ssl_crl) {
969 		rfbLog("CRL_check: skipped.\n");
970 		return ok;
971 	}
972 	if (!ok) {
973 		rfbLog("CRL_check: client cert is already rejected.\n");
974 		return ok;
975 	}
976 	if (revocation_store) {
977 		if (crl_callback(callback_ctx)) {
978 			rfbLog("CRL_check: succeeded.\n");
979 			return 1;
980 		} else {
981 			rfbLog("CRL_check: did not pass.\n");
982 			return 0;
983 		}
984 	}
985 	/* NOTREACHED */
986 	return 1;
987 }
988 
989 #define rfbSecTypeAnonTls  18
990 #define rfbSecTypeVencrypt 19
991 
992 #define rfbVencryptPlain	256
993 #define rfbVencryptTlsNone	257
994 #define rfbVencryptTlsVnc	258
995 #define rfbVencryptTlsPlain	259
996 #define rfbVencryptX509None	260
997 #define rfbVencryptX509Vnc	261
998 #define rfbVencryptX509Plain	262
999 
1000 static int ssl_client_mode = 0;
1001 
1002 static int switch_to_anon_dh(void);
1003 
openssl_init(int isclient)1004 void openssl_init(int isclient) {
1005 	int db = 0, tmp_pem = 0, do_dh;
1006 	const SSL_METHOD *method;
1007 	char *method_name;
1008 	FILE *in;
1009 	double ds;
1010 	long mode;
1011 	static int first = 1;
1012 
1013 	do_dh = DO_DH;
1014 
1015 	if (enc_str != NULL) {
1016 		if (first) {
1017 			init_prng();
1018 		}
1019 		first = 0;
1020 		return;
1021 	}
1022 
1023 	if (! quiet) {
1024 		rfbLog("\n");
1025 		rfbLog("Initializing SSL (%s connect mode).\n", isclient ? "client":"server");
1026 	}
1027 	if (first) {
1028 		if (db) fprintf(stderr, "\nSSL_load_error_strings()\n");
1029 
1030 		SSL_load_error_strings();
1031 
1032 		if (db) fprintf(stderr, "SSL_library_init()\n");
1033 
1034 		SSL_library_init();
1035 
1036 		if (db) fprintf(stderr, "init_prng()\n");
1037 
1038 		init_prng();
1039 
1040 		first = 0;
1041 	}
1042 
1043 	if (isclient) {
1044 		ssl_client_mode = 1;
1045 	} else {
1046 		ssl_client_mode = 0;
1047 	}
1048 
1049 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
1050 	method = ssl_client_mode ? TLS_client_method() : TLS_server_method();
1051 	if (db)
1052 		method_name = ssl_client_mode ? "TLS_client_method()" : "TLS_server_method()";
1053 #else
1054 	method = ssl_client_mode ? SSLv23_client_method() : SSLv23_server_method();
1055 	if (db)
1056 		method_name = ssl_client_mode ? "SSLv23_client_method()" : "SSLv23_server_method()";
1057 #endif
1058 	if (db) fprintf(stderr, "%s\n", method_name);
1059 	ctx = SSL_CTX_new(method);
1060 
1061 	if (ctx == NULL) {
1062 		rfbLog("openssl_init: SSL_CTX_new failed.\n");
1063 		sslerrexit();
1064 	}
1065 
1066 	ds = dnow();
1067 	rsa_512 = RSA_generate_key(512, RSA_F4, NULL, NULL);
1068 	if (rsa_512 == NULL) {
1069 		rfbLog("openssl_init: RSA_generate_key(512) failed.\n");
1070 		sslerrexit();
1071 	}
1072 
1073 	rfbLog("created  512 bit temporary RSA key: %.3fs\n", dnow() - ds);
1074 
1075 	ds = dnow();
1076 	rsa_1024 = RSA_generate_key(1024, RSA_F4, NULL, NULL);
1077 	if (rsa_1024 == NULL) {
1078 		rfbLog("openssl_init: RSA_generate_key(1024) failed.\n");
1079 		sslerrexit();
1080 	}
1081 
1082 	rfbLog("created 1024 bit temporary RSA key: %.3fs\n", dnow() - ds);
1083 
1084 	if (db) fprintf(stderr, "SSL_CTX_set_tmp_rsa()\n");
1085 
1086 	if (! SSL_CTX_set_tmp_rsa(ctx, rsa_1024)) {
1087 		rfbLog("openssl_init: SSL_CTX_set_tmp_rsa(1024) failed.\n");
1088 		sslerrexit();
1089 	}
1090 
1091 	mode = 0;
1092 	mode |= SSL_MODE_ENABLE_PARTIAL_WRITE;
1093 	mode |= SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER;
1094 	SSL_CTX_set_mode(ctx, mode);
1095 
1096 #define ssl_cache 0
1097 #if ssl_cache
1098 	SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH);
1099 	SSL_CTX_set_timeout(ctx, 300);
1100 #else
1101 	SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
1102 	SSL_CTX_set_timeout(ctx, 1);
1103 #endif
1104 
1105 	ds = dnow();
1106 	if (! openssl_pem) {
1107 		openssl_pem = create_tmp_pem(NULL, 0);
1108 		if (! openssl_pem) {
1109 			rfbLog("openssl_init: could not create temporary,"
1110 			    " self-signed PEM.\n");
1111 			clean_up_exit(1);
1112 		}
1113 		tmp_pem = 1;
1114 
1115 	} else if (!strcmp(openssl_pem, "ANON")) {
1116 		if (ssl_verify) {
1117 			rfbLog("openssl_init: Anonymous Diffie-Hellman cannot"
1118 			    " be used in -sslverify mode.\n");
1119 			clean_up_exit(1);
1120 		}
1121 		if (ssl_crl) {
1122 			rfbLog("openssl_init: Anonymous Diffie-Hellman cannot"
1123 			    " be used in -sslCRL mode.\n");
1124 			clean_up_exit(1);
1125 		}
1126 		/* n.b. new ctx */
1127 		if (!switch_to_anon_dh()) {
1128 			rfbLog("openssl_init: Anonymous Diffie-Hellman setup"
1129 			    " failed.\n");
1130 			clean_up_exit(1);
1131 		}
1132 	} else if (strstr(openssl_pem, "SAVE") == openssl_pem) {
1133 		openssl_pem = get_saved_pem(openssl_pem, 1);
1134 		if (! openssl_pem) {
1135 			rfbLog("openssl_init: could not create or open"
1136 			    " saved PEM: %s\n", openssl_pem);
1137 			clean_up_exit(1);
1138 		}
1139 		tmp_pem = 0;
1140 	}
1141 
1142 	rfbLog("using PEM %s  %.3fs\n", openssl_pem, dnow() - ds);
1143 
1144 	SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_callback);
1145 
1146 	if (do_dh) {
1147 		DH *dh;
1148 		BIO *bio;
1149 
1150 		ds = dnow();
1151 		in = fopen(openssl_pem, "r");
1152 		if (in == NULL) {
1153 			rfbLogPerror("fopen");
1154 			clean_up_exit(1);
1155 		}
1156 		bio = BIO_new_fp(in, BIO_CLOSE|BIO_FP_TEXT);
1157 		if (! bio) {
1158 			rfbLog("openssl_init: BIO_new_fp() failed.\n");
1159 			sslerrexit();
1160 		}
1161 		dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
1162 		if (dh == NULL) {
1163 			rfbLog("openssl_init: PEM_read_bio_DHparams() failed.\n");
1164 			BIO_free(bio);
1165 			sslerrexit();
1166 		}
1167 		BIO_free(bio);
1168 		SSL_CTX_set_tmp_dh(ctx, dh);
1169 		rfbLog("loaded Diffie Hellman %d bits, %.3fs\n",
1170 		    8*DH_size(dh), dnow()-ds);
1171 		DH_free(dh);
1172 	}
1173 
1174 	if (strcmp(openssl_pem, "ANON")) {
1175 		if (! SSL_CTX_use_certificate_chain_file(ctx, openssl_pem)) {
1176 			rfbLog("openssl_init: SSL_CTX_use_certificate_chain_file() failed.\n");
1177 			sslerrexit();
1178 		}
1179 		if (! SSL_CTX_use_RSAPrivateKey_file(ctx, openssl_pem,
1180 		    SSL_FILETYPE_PEM)) {
1181 			rfbLog("openssl_init: SSL_CTX_set_tmp_rsa(1024) failed.\n");
1182 			sslerrexit();
1183 		}
1184 		if (! SSL_CTX_check_private_key(ctx)) {
1185 			rfbLog("openssl_init: SSL_CTX_set_tmp_rsa(1024) failed.\n");
1186 			sslerrexit();
1187 		}
1188 	}
1189 
1190 	if (tmp_pem && ! getenv("X11VNC_KEEP_TMP_PEM")) {
1191 		if (getenv("X11VNC_SHOW_TMP_PEM")) {
1192 			FILE *in = fopen(openssl_pem, "r");
1193 			if (in != NULL) {
1194 				char line[128];
1195 				fprintf(stderr, "\n");
1196 				while (fgets(line, 128, in) != NULL) {
1197 					fprintf(stderr, "%s", line);
1198 				}
1199 				fprintf(stderr, "\n");
1200 				fclose(in);
1201 			}
1202 		}
1203 		unlink(openssl_pem);
1204 		free(openssl_pem);
1205 		openssl_pem = NULL;
1206 	}
1207 
1208 	if (ssl_crl) {
1209 		struct stat sbuf;
1210 		X509_LOOKUP *lookup;
1211 
1212 		if (stat(ssl_crl, &sbuf) != 0) {
1213 			rfbLog("openssl_init: -sslCRL does not exist %s.\n",
1214 			    ssl_crl ? ssl_crl : "null");
1215 			rfbLogPerror("stat");
1216 			clean_up_exit(1);
1217 		}
1218 
1219 		revocation_store = X509_STORE_new();
1220 		if (!revocation_store) {
1221 			rfbLog("openssl_init: X509_STORE_new failed.\n");
1222 			sslerrexit();
1223 		}
1224 		if (! S_ISDIR(sbuf.st_mode)) {
1225 			lookup = X509_STORE_add_lookup(revocation_store, X509_LOOKUP_file());
1226 			if (!lookup) {
1227 				rfbLog("openssl_init: X509_STORE_add_lookup failed.\n");
1228 				sslerrexit();
1229 			}
1230 			if (!X509_LOOKUP_load_file(lookup, ssl_crl, X509_FILETYPE_PEM))  {
1231 				rfbLog("openssl_init: X509_LOOKUP_load_file failed.\n");
1232 				sslerrexit();
1233 			}
1234 		} else {
1235 			lookup = X509_STORE_add_lookup(revocation_store, X509_LOOKUP_hash_dir());
1236 			if (!lookup) {
1237 				rfbLog("openssl_init: X509_STORE_add_lookup failed.\n");
1238 				sslerrexit();
1239 			}
1240 			if (!X509_LOOKUP_add_dir(lookup, ssl_crl, X509_FILETYPE_PEM))  {
1241 				rfbLog("openssl_init: X509_LOOKUP_add_dir failed.\n");
1242 				sslerrexit();
1243 			}
1244 		}
1245 		rfbLog("loaded CRL file: %s\n", ssl_crl);
1246 	}
1247 
1248 	if (ssl_verify) {
1249 		struct stat sbuf;
1250 		char *file;
1251 		int lvl;
1252 
1253 		file = get_ssl_verify_file(ssl_verify);
1254 
1255 		if (!file || stat(file, &sbuf) != 0) {
1256 			rfbLog("openssl_init: -sslverify does not exist %s.\n",
1257 			    file ? file : "null");
1258 			rfbLogPerror("stat");
1259 			clean_up_exit(1);
1260 		}
1261 		if (! S_ISDIR(sbuf.st_mode)) {
1262 			if (! SSL_CTX_load_verify_locations(ctx, file, NULL)) {
1263 				rfbLog("openssl_init: SSL_CTX_load_verify_"
1264 				    "locations() failed.\n");
1265 				sslerrexit();
1266 			}
1267 		} else {
1268 			if (! SSL_CTX_load_verify_locations(ctx, NULL, file)) {
1269 				rfbLog("openssl_init: SSL_CTX_load_verify_"
1270 				    "locations() failed.\n");
1271 				sslerrexit();
1272 			}
1273 		}
1274 
1275 		lvl = SSL_VERIFY_FAIL_IF_NO_PEER_CERT|SSL_VERIFY_PEER;
1276 		if (ssl_crl == NULL) {
1277 			SSL_CTX_set_verify(ctx, lvl, NULL);
1278 		} else {
1279 			SSL_CTX_set_verify(ctx, lvl, verify_callback);
1280 		}
1281 		if (strstr(file, "/sslverify-tmp-load-")) {
1282 			/* temporary file */
1283 			unlink(file);
1284 		}
1285 	} else {
1286 		SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
1287 	}
1288 
1289 	rfbLog("\n");
1290 }
1291 
read_exact(int sock,char * buf,int len)1292 static int read_exact(int sock, char *buf, int len) {
1293 	int n, fail = 0;
1294 	if (sock < 0) {
1295 		return 0;
1296 	}
1297 	while (len > 0) {
1298 		n = read(sock, buf, len);
1299 		if (n > 0) {
1300 			buf += n;
1301 			len -= n;
1302 		} else if (n == 0) {
1303 			fail = 1;
1304 			break;
1305 		} else if (n < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
1306 			usleep(10*1000);
1307 		} else if (n < 0 && errno != EINTR) {
1308 			fail = 1;
1309 			break;
1310 		}
1311 	}
1312 	if (fail) {
1313 		return 0;
1314 	} else {
1315 		return 1;
1316 	}
1317 }
1318 
write_exact(int sock,char * buf,int len)1319 static int write_exact(int sock, char *buf, int len) {
1320 	int n, fail = 0;
1321 	if (sock < 0) {
1322 		return 0;
1323 	}
1324 	while (len > 0) {
1325 		n = write(sock, buf, len);
1326 		if (n > 0) {
1327 			buf += n;
1328 			len -= n;
1329 		} else if (n == 0) {
1330 			fail = 1;
1331 			break;
1332 		} else if (n < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
1333 			usleep(10*1000);
1334 		} else if (n < 0 && errno != EINTR) {
1335 			fail = 1;
1336 			break;
1337 		}
1338 	}
1339 	if (fail) {
1340 		return 0;
1341 	} else {
1342 		return 1;
1343 	}
1344 }
1345 
1346 /* XXX not in rfb.h: */
1347 void rfbClientSendString(rfbClientPtr cl, char *reason);
1348 
finish_auth(rfbClientPtr client,char * type)1349 static int finish_auth(rfbClientPtr client, char *type) {
1350 	int security_result, ret;
1351 
1352 	ret = 0;
1353 
1354 if (getenv("X11VNC_DEBUG_TLSPLAIN")) fprintf(stderr, "finish_auth type=%s\n", type);
1355 
1356 	if (!strcmp(type, "None")) {
1357 		security_result = 0;	/* success */
1358 		if (write_exact(client->sock, (char *) &security_result, 4)) {
1359 			ret = 1;
1360 		}
1361 		rfbLog("finish_auth: using auth 'None'\n");
1362 		client->state = RFB_INITIALISATION;
1363 
1364 	} else if (!strcmp(type, "Vnc")) {
1365 		RAND_bytes(client->authChallenge, CHALLENGESIZE);
1366 		if (write_exact(client->sock, (char *) &client->authChallenge, CHALLENGESIZE)) {
1367 			ret = 1;
1368 		}
1369 		rfbLog("finish_auth: using auth 'Vnc', sent challenge.\n");
1370 		client->state = RFB_AUTHENTICATION;
1371 
1372 	} else if (!strcmp(type, "Plain")) {
1373 		if (!unixpw) {
1374 			rfbLog("finish_auth: *Plain not allowed outside unixpw mode.\n");
1375 			ret = 0;
1376 		} else {
1377 			char *un, *pw;
1378 			int unlen, pwlen;
1379 
1380 if (getenv("X11VNC_DEBUG_TLSPLAIN")) fprintf(stderr, "*Plain begin: onHold=%d client=%p unixpw_client=%p\n", client->onHold, (void *) client, (void *) unixpw_client);
1381 
1382 			if (!read_exact(client->sock, (char *)&unlen, 4)) goto fail;
1383 			unlen = Swap32IfLE(unlen);
1384 
1385 if (getenv("X11VNC_DEBUG_TLSPLAIN")) fprintf(stderr, "unlen: %d\n", unlen);
1386 
1387 			if (!read_exact(client->sock, (char *)&pwlen, 4)) goto fail;
1388 			pwlen = Swap32IfLE(pwlen);
1389 
1390 if (getenv("X11VNC_DEBUG_TLSPLAIN")) fprintf(stderr, "pwlen: %d\n", pwlen);
1391 
1392 			un = (char *) malloc(unlen+1);
1393 			memset(un, 0, unlen+1);
1394 
1395 			pw = (char *) malloc(pwlen+2);
1396 			memset(pw, 0, pwlen+2);
1397 
1398 			if (!read_exact(client->sock, un, unlen)) goto fail;
1399 			if (!read_exact(client->sock, pw, pwlen)) goto fail;
1400 
1401 if (getenv("X11VNC_DEBUG_TLSPLAIN")) fprintf(stderr, "*Plain: %d %d '%s' ... \n", unlen, pwlen, un);
1402 			strcat(pw, "\n");
1403 
1404 			if (unixpw_verify(un, pw)) {
1405 				security_result = 0;	/* success */
1406 				if (write_exact(client->sock, (char *) &security_result, 4)) {
1407 					ret = 1;
1408 					unixpw_verify_screen(un, pw);
1409 				}
1410 				client->onHold = FALSE;
1411 				client->state = RFB_INITIALISATION;
1412 			}
1413 			if (ret == 0) {
1414 				rfbClientSendString(client, "unixpw failed");
1415 			}
1416 
1417 			memset(un, 0, unlen+1);
1418 			memset(pw, 0, pwlen+2);
1419 			free(un);
1420 			free(pw);
1421 		}
1422 	} else {
1423 		rfbLog("finish_auth: unknown sub-type: %s\n", type);
1424 		ret = 0;
1425 	}
1426 
1427 	fail:
1428 	return ret;
1429 }
1430 
finish_vencrypt_auth(rfbClientPtr client,int subtype)1431 static int finish_vencrypt_auth(rfbClientPtr client, int subtype) {
1432 
1433 	if (subtype == rfbVencryptTlsNone || subtype == rfbVencryptX509None) {
1434 		return finish_auth(client, "None");
1435 	} else if (subtype == rfbVencryptTlsVnc || subtype == rfbVencryptX509Vnc) {
1436 		return finish_auth(client, "Vnc");
1437 	} else if (subtype == rfbVencryptTlsPlain || subtype == rfbVencryptX509Plain) {
1438 		return finish_auth(client, "Plain");
1439 	} else {
1440 		rfbLog("finish_vencrypt_auth: unknown sub-type: %d\n", subtype);
1441 		return 0;
1442 	}
1443 }
1444 
1445 
add_anon_dh(void)1446 static int add_anon_dh(void) {
1447 	pid_t pid, pidw;
1448 	char cnf[] = "/tmp/x11vnc-dh.XXXXXX";
1449 	char *infile = NULL;
1450 	int status, cnf_fd;
1451 	DH *dh;
1452 	BIO *bio;
1453 	FILE *in;
1454 	double ds;
1455 	/*
1456 	 * These are dh parameters (prime, generator), not dh keys.
1457 	 * Evidently it is ok for them to be publicly known.
1458 	 * openssl dhparam -out dh.out 1024
1459 	 */
1460 	char *fixed_dh_params =
1461 "-----BEGIN DH PARAMETERS-----\n"
1462 "MIGHAoGBAL28w69ZnLYBvp8R2OeqtAIms+oatY19iBL4WhGI/7H1OMmkJjIe+OHs\n"
1463 "PXoJfe5ucrnvno7Xm+HJZYa1jnPGQuWoa/VJKXdVjYdJVNzazJKM2daKKcQA4GDc\n"
1464 "msFS5DxLbzUR5jy1n12K3EcbvpyFqDYVTJJXm7NuNuiWRfz3wTozAgEC\n"
1465 "-----END DH PARAMETERS-----\n";
1466 
1467 	if (dhparams_file != NULL) {
1468 		infile = dhparams_file;
1469 		rfbLog("add_anon_dh: using %s\n", dhparams_file);
1470 		goto readin;
1471 	}
1472 
1473 	cnf_fd = mkstemp(cnf);
1474 	if (cnf_fd < 0) {
1475 		return 0;
1476 	}
1477 	infile = cnf;
1478 
1479 	if (create_fresh_dhparams) {
1480 
1481 		if (new_dh_params != NULL) {
1482 			write(cnf_fd, new_dh_params, strlen(new_dh_params));
1483 			close(cnf_fd);
1484 		} else {
1485 			char *exe = find_openssl_bin();
1486 			struct stat sbuf;
1487 
1488 			if (no_external_cmds || !cmd_ok("ssl")) {
1489 				rfbLog("add_anon_dh: cannot run external commands.\n");
1490 				return 0;
1491 			}
1492 
1493 			close(cnf_fd);
1494 			if (exe == NULL) {
1495 				return 0;
1496 			}
1497 			ds = dnow();
1498 			pid = fork();
1499 			if (pid < 0) {
1500 				return 0;
1501 			} else if (pid == 0) {
1502 				int i;
1503 				for (i=0; i<256; i++) {
1504 					if (i == 2) continue;
1505 					close(i);
1506 				}
1507 				/* rather slow at 1024 */
1508 				execlp(exe, exe, "dhparam", "-out", cnf, "1024", (char *)0);
1509 				exit(1);
1510 			}
1511 			pidw = waitpid(pid, &status, 0);
1512 			if (pidw != pid) {
1513 				return 0;
1514 			}
1515 			if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
1516 				;
1517 			} else {
1518 				return 0;
1519 			}
1520 			rfbLog("add_anon_dh: created new DH params in %.3f secs\n", dnow() - ds);
1521 
1522 			if (stat(cnf, &sbuf) == 0 && sbuf.st_size > 0) {
1523 				/* save it to reuse during our process's lifetime: */
1524 				int d = open(cnf, O_RDONLY);
1525 				if (d >= 0) {
1526 					int n, len = sbuf.st_size;
1527 					new_dh_params = (char *) calloc(len+1, 1);
1528 					n = read(d, new_dh_params, len);
1529 					close(d);
1530 					if (n != len) {
1531 						free(new_dh_params);
1532 						new_dh_params = NULL;
1533 					} else if (dhret != NULL) {
1534 						d = open(dhret, O_WRONLY);
1535 						if (d >= 0) {
1536 							write(d, new_dh_params, strlen(new_dh_params));
1537 							close(d);
1538 						}
1539 					}
1540 				}
1541 			}
1542 		}
1543 	} else {
1544 		write(cnf_fd, fixed_dh_params, strlen(fixed_dh_params));
1545 		close(cnf_fd);
1546 	}
1547 
1548 	readin:
1549 
1550 	ds = dnow();
1551 	in = fopen(infile, "r");
1552 
1553 	if (in == NULL) {
1554 		rfbLogPerror("fopen");
1555 		unlink(cnf);
1556 		return 0;
1557 	}
1558 	bio = BIO_new_fp(in, BIO_CLOSE|BIO_FP_TEXT);
1559 	if (! bio) {
1560 		rfbLog("openssl_init: BIO_new_fp() failed.\n");
1561 		unlink(cnf);
1562 		return 0;
1563 	}
1564 	dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
1565 	if (dh == NULL) {
1566 		rfbLog("openssl_init: PEM_read_bio_DHparams() failed.\n");
1567 		unlink(cnf);
1568 		BIO_free(bio);
1569 		return 0;
1570 	}
1571 	BIO_free(bio);
1572 	SSL_CTX_set_tmp_dh(ctx, dh);
1573 	rfbLog("loaded Diffie Hellman %d bits, %.3fs\n", 8*DH_size(dh), dnow()-ds);
1574 	DH_free(dh);
1575 
1576 	unlink(cnf);
1577 	return 1;
1578 }
1579 
switch_to_anon_dh(void)1580 static int switch_to_anon_dh(void) {
1581 	const SSL_METHOD *method;
1582 	long mode;
1583 
1584 	rfbLog("Using Anonymous Diffie-Hellman mode.\n");
1585 	rfbLog("WARNING: Anonymous Diffie-Hellman uses encryption but is\n");
1586 	rfbLog("WARNING: susceptible to a Man-In-The-Middle attack.\n");
1587 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
1588 	method = ssl_client_mode ? TLS_client_method() : TLS_server_method();
1589 #else
1590 	method = ssl_client_mode ? SSLv23_client_method() : SSLv23_server_method();
1591 #endif
1592 	ctx = SSL_CTX_new(method);
1593 	if (ctx == NULL) {
1594 		return 0;
1595 	}
1596 	if (ssl_client_mode) {
1597 		return 1;
1598 	}
1599 	if (!SSL_CTX_set_cipher_list(ctx, "ADH:@STRENGTH")) {
1600 		return 0;
1601 	}
1602 	if (!add_anon_dh()) {
1603 		return 0;
1604 	}
1605 
1606 	mode = 0;
1607 	mode |= SSL_MODE_ENABLE_PARTIAL_WRITE;
1608 	mode |= SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER;
1609 	SSL_CTX_set_mode(ctx, mode);
1610 
1611 	SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH);
1612 	SSL_CTX_set_timeout(ctx, 300);
1613 	SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_callback);
1614 	SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
1615 
1616 	return 1;
1617 }
1618 
anontls_dialog(int s_in,int s_out)1619 static int anontls_dialog(int s_in, int s_out) {
1620 
1621 	if (s_in || s_out) {}
1622 	anontls_selected = 1;
1623 
1624 	if (!switch_to_anon_dh()) {
1625 		rfbLog("anontls: Anonymous Diffie-Hellman failed.\n");
1626 		return 0;
1627 	}
1628 
1629 	/* continue with SSL/TLS */
1630 	return 1;
1631 }
1632 
1633 /*
1634  * Using spec:
1635  * http://www.mail-archive.com/qemu-devel@nongnu.org/msg08681.html
1636  */
vencrypt_dialog(int s_in,int s_out)1637 static int vencrypt_dialog(int s_in, int s_out) {
1638 	char buf[256], buf2[256];
1639 	int subtypes[16];
1640 	int n, i, ival, ok, nsubtypes = 0;
1641 
1642 	vencrypt_selected = 0;
1643 
1644 	/* send version 0.2 */
1645 	buf[0] = 0;
1646 	buf[1] = 2;
1647 
1648 	if (!write_exact(s_out, buf, 2)) {
1649 		close(s_in); close(s_out);
1650 		return 0;
1651 	}
1652 
1653 	/* read client version 0.2 */
1654 	memset(buf, 0, sizeof(buf));
1655 	if (!read_exact(s_in, buf, 2)) {
1656 		close(s_in); close(s_out);
1657 		return 0;
1658 	}
1659 	rfbLog("vencrypt: received %d.%d client version.\n", (int) buf[0], (int) buf[1]);
1660 
1661 	/* close 0.0 */
1662 	if (buf[0] == 0 && buf[1] == 0) {
1663 		rfbLog("vencrypt: received 0.0 version, closing connection.\n");
1664 		close(s_in); close(s_out);
1665 		return 0;
1666 	}
1667 
1668 	/* accept only 0.2 */
1669 	if (buf[0] != 0 || buf[1] != 2) {
1670 		rfbLog("vencrypt: unsupported VeNCrypt version, closing connection.\n");
1671 		buf[0] = (char) 255;
1672 		write_exact(s_out, buf, 1);
1673 		close(s_in); close(s_out);
1674 		return 0;
1675 	}
1676 
1677 	/* tell them OK */
1678 	buf[0] = 0;
1679 	if (!write_exact(s_out, buf, 1)) {
1680 		close(s_in); close(s_out);
1681 		return 0;
1682 	}
1683 
1684 	if (getenv("X11VNC_ENABLE_VENCRYPT_PLAIN_LOGIN")) {
1685 		vencrypt_enable_plain_login = atoi(getenv("X11VNC_ENABLE_VENCRYPT_PLAIN_LOGIN"));
1686 	}
1687 
1688 	/* load our list of sub-types: */
1689 	n = 0;
1690 	if (!ssl_verify && vencrypt_kx != VENCRYPT_NODH) {
1691 		if (screen->authPasswdData != NULL) {
1692 			subtypes[n++] = rfbVencryptTlsVnc;
1693 		} else {
1694 			if (vencrypt_enable_plain_login && unixpw) {
1695 				subtypes[n++] = rfbVencryptTlsPlain;
1696 			} else {
1697 				subtypes[n++] = rfbVencryptTlsNone;
1698 			}
1699 		}
1700 	}
1701 	if (vencrypt_kx != VENCRYPT_NOX509) {
1702 		if (screen->authPasswdData != NULL) {
1703 			subtypes[n++] = rfbVencryptX509Vnc;
1704 		} else {
1705 			if (vencrypt_enable_plain_login && unixpw) {
1706 				subtypes[n++] = rfbVencryptX509Plain;
1707 			} else {
1708 				subtypes[n++] = rfbVencryptX509None;
1709 			}
1710 		}
1711 	}
1712 
1713 	nsubtypes = n;
1714 	for (i = 0; i < nsubtypes; i++) {
1715 		((uint32_t *)buf)[i] = Swap32IfLE(subtypes[i]);
1716 	}
1717 
1718 	/* send number first: */
1719 	buf2[0] = (char) nsubtypes;
1720 	if (!write_exact(s_out, buf2, 1)) {
1721 		close(s_in); close(s_out);
1722 		return 0;
1723 	}
1724 	/* and now the list: */
1725 	if (!write_exact(s_out, buf, 4*n)) {
1726 		close(s_in); close(s_out);
1727 		return 0;
1728 	}
1729 
1730 	/* read client's selection: */
1731 	if (!read_exact(s_in, (char *)&ival, 4)) {
1732 		close(s_in); close(s_out);
1733 		return 0;
1734 	}
1735 	ival = Swap32IfLE(ival);
1736 
1737 	/* zero means no dice: */
1738 	if (ival == 0) {
1739 		rfbLog("vencrypt: client selected no sub-type, closing connection.\n");
1740 		close(s_in); close(s_out);
1741 		return 0;
1742 	}
1743 
1744 	/* check if he selected a valid one: */
1745 	ok = 0;
1746 	for (i = 0; i < nsubtypes; i++) {
1747 		if (ival == subtypes[i]) {
1748 			ok = 1;
1749 		}
1750 	}
1751 
1752 	if (!ok) {
1753 		rfbLog("vencrypt: client selected invalid sub-type: %d\n", ival);
1754 		close(s_in); close(s_out);
1755 		return 0;
1756 	} else {
1757 		char *st = "unknown!!";
1758 		if (ival == rfbVencryptTlsNone)	  st = "rfbVencryptTlsNone";
1759 		if (ival == rfbVencryptTlsVnc)    st = "rfbVencryptTlsVnc";
1760 		if (ival == rfbVencryptTlsPlain)  st = "rfbVencryptTlsPlain";
1761 		if (ival == rfbVencryptX509None)  st = "rfbVencryptX509None";
1762 		if (ival == rfbVencryptX509Vnc)   st = "rfbVencryptX509Vnc";
1763 		if (ival == rfbVencryptX509Plain) st = "rfbVencryptX509Plain";
1764 		rfbLog("vencrypt: client selected sub-type: %d (%s)\n", ival, st);
1765 	}
1766 
1767 	vencrypt_selected = ival;
1768 
1769 	/* not documented in spec, send OK: */
1770 	buf[0] = 1;
1771 	if (!write_exact(s_out, buf, 1)) {
1772 		close(s_in); close(s_out);
1773 		return 0;
1774 	}
1775 
1776 	if (vencrypt_selected == rfbVencryptTlsNone ||
1777 	    vencrypt_selected == rfbVencryptTlsVnc  ||
1778 	    vencrypt_selected == rfbVencryptTlsPlain) {
1779 		/* these modes are Anonymous Diffie-Hellman */
1780 		if (!switch_to_anon_dh()) {
1781 			rfbLog("vencrypt: Anonymous Diffie-Hellman failed.\n");
1782 			return 0;
1783 		}
1784 	}
1785 
1786 	/* continue with SSL/TLS */
1787 	return 1;
1788 }
1789 
check_vnc_tls_mode(int s_in,int s_out,double last_https)1790 static int check_vnc_tls_mode(int s_in, int s_out, double last_https) {
1791 	double waited = 0.0, waitmax = 1.4, dt = 0.01, start = dnow();
1792 	struct timeval tv;
1793 	int input = 0, i, n, ok;
1794 	int major, minor, sectype = -1;
1795 	char *proto = "RFB 003.008\n";
1796 	char *stype = "unknown";
1797 	char buf[256];
1798 
1799 	vencrypt_selected = 0;
1800 	anontls_selected = 0;
1801 
1802 	if (vencrypt_mode == VENCRYPT_NONE && anontls_mode == ANONTLS_NONE) {
1803 		/* only normal SSL */
1804 		return 1;
1805 	}
1806 	if (ssl_client_mode) {
1807 		if (vencrypt_mode == VENCRYPT_FORCE || anontls_mode == ANONTLS_FORCE) {
1808 			rfbLog("check_vnc_tls_mode: VENCRYPT_FORCE/ANONTLS_FORCE in client\n");
1809 			rfbLog("check_vnc_tls_mode: connect mode.\n");
1810 			/* this is OK, continue on below for dialog. */
1811 		} else {
1812 			/* otherwise we must assume normal SSL (we send client hello) */
1813 			return 1;
1814 		}
1815 	}
1816 	if (ssl_verify && vencrypt_mode != VENCRYPT_FORCE && anontls_mode == ANONTLS_FORCE) {
1817 		rfbLog("check_vnc_tls_mode: Cannot use ANONTLS_FORCE with -sslverify (Anon DH only)\n");
1818 		/* fallback to normal SSL */
1819 		return 1;
1820 	}
1821 
1822 	if (last_https > 0.0) {
1823 		double now = dnow();
1824 		if (now < last_https + 5.0) {
1825 			waitmax = 20.0;
1826 		} else if (now < last_https + 15.0) {
1827 			waitmax = 10.0;
1828 		} else if (now < last_https + 30.0) {
1829 			waitmax = 5.0;
1830 		} else if (now < last_https + 60.0) {
1831 			waitmax = 2.5;
1832 		}
1833 	}
1834 
1835 	while (waited < waitmax) {
1836 		fd_set rfds;
1837 		FD_ZERO(&rfds);
1838 		FD_SET(s_in, &rfds);
1839 		tv.tv_sec = 0;
1840 		tv.tv_usec = 0;
1841 		select(s_in+1, &rfds, NULL, NULL, &tv);
1842 		if (FD_ISSET(s_in, &rfds)) {
1843 			input = 1;
1844 			break;
1845 		}
1846 		usleep((int) (1000 * 1000 * dt));
1847 		waited += dt;
1848 	}
1849 	rfbLog("check_vnc_tls_mode: waited: %f / %.2f input: %s\n",
1850 	    dnow() - start, waitmax, input ? "SSL Handshake" : "(future) RFB Handshake");
1851 
1852 	if (input) {
1853 		/* got SSL client hello, can only assume normal SSL */
1854 		if (vencrypt_mode == VENCRYPT_FORCE || anontls_mode == ANONTLS_FORCE) {
1855 			rfbLog("check_vnc_tls_mode: VENCRYPT_FORCE/ANONTLS_FORCE prevents normal SSL\n");
1856 			return 0;
1857 		}
1858 		return 1;
1859 	}
1860 
1861 	/* send RFB 003.008 -- there is no turning back from this point... */
1862 	if (!write_exact(s_out, proto, strlen(proto))) {
1863 		close(s_in); close(s_out);
1864 		return 0;
1865 	}
1866 
1867 	memset(buf, 0, sizeof(buf));
1868 	if (!read_exact(s_in, buf, 12)) {
1869 		close(s_in); close(s_out);
1870 		return 0;
1871 	}
1872 
1873 	if (sscanf(buf, "RFB %03d.%03d\n", &major, &minor) != 2) {
1874 		int i;
1875 		rfbLog("check_vnc_tls_mode: abnormal handshake: '%s'\nbytes: ", buf);
1876 		for (i=0; i < 12; i++) {
1877 			fprintf(stderr, "%d.", (unsigned char) buf[i]);
1878 		}
1879 		fprintf(stderr, "\n");
1880 		close(s_in); close(s_out);
1881 		return 0;
1882 	}
1883 	rfbLog("check_vnc_tls_mode: version: %d.%d\n", major, minor);
1884 	if (major != 3 || minor < 8) {
1885 		rfbLog("check_vnc_tls_mode: invalid version: '%s'\n", buf);
1886 		close(s_in); close(s_out);
1887 		return 0;
1888 	}
1889 
1890 	n = 1;
1891 	if (vencrypt_mode == VENCRYPT_FORCE) {
1892 		buf[n++] = rfbSecTypeVencrypt;
1893 	} else if (anontls_mode == ANONTLS_FORCE && !ssl_verify) {
1894 		buf[n++] = rfbSecTypeAnonTls;
1895 	} else if (vencrypt_mode == VENCRYPT_SOLE) {
1896 		buf[n++] = rfbSecTypeVencrypt;
1897 	} else if (anontls_mode == ANONTLS_SOLE && !ssl_verify) {
1898 		buf[n++] = rfbSecTypeAnonTls;
1899 	} else {
1900 		if (vencrypt_mode == VENCRYPT_SUPPORT) {
1901 			buf[n++] = rfbSecTypeVencrypt;
1902 		}
1903 		if (anontls_mode == ANONTLS_SUPPORT && !ssl_verify) {
1904 			buf[n++] = rfbSecTypeAnonTls;
1905 		}
1906 	}
1907 
1908 	n--;
1909 	buf[0] = (char) n;
1910 	if (!write_exact(s_out, buf, n+1)) {
1911 		close(s_in); close(s_out);
1912 		return 0;
1913 	}
1914 	if (0) fprintf(stderr, "wrote[%d] %d %d %d\n", n, buf[0], buf[1], buf[2]);
1915 
1916 	buf[0] = 0;
1917 	if (!read_exact(s_in, buf, 1)) {
1918 		close(s_in); close(s_out);
1919 		return 0;
1920 	}
1921 
1922 	if (buf[0] == rfbSecTypeVencrypt) stype = "VeNCrypt";
1923 	if (buf[0] == rfbSecTypeAnonTls)  stype = "ANONTLS";
1924 
1925 	rfbLog("check_vnc_tls_mode: reply: %d (%s)\n", (int) buf[0], stype);
1926 
1927 	ok = 0;
1928 	for (i=1; i < n+1; i++) {
1929 		if (buf[0] == buf[i]) {
1930 			ok = 1;
1931 		}
1932 	}
1933 	if (!ok) {
1934 		char *msg = "check_vnc_tls_mode: invalid security-type";
1935 		int len = strlen(msg);
1936 		rfbLog("%s: %d\n", msg, (int) buf[0]);
1937 		((uint32_t *)buf)[0] = Swap32IfLE(len);
1938 		write_exact(s_out, buf, 4);
1939 		write_exact(s_out, msg, strlen(msg));
1940 		close(s_in); close(s_out);
1941 		return 0;
1942 	}
1943 
1944 	sectype = (int) buf[0];
1945 
1946 	if (sectype == rfbSecTypeVencrypt) {
1947 		return vencrypt_dialog(s_in, s_out);
1948 	} else if (sectype == rfbSecTypeAnonTls) {
1949 		return anontls_dialog(s_in, s_out);
1950 	} else {
1951 		return 0;
1952 	}
1953 }
1954 
pr_ssl_info(int verb)1955 static void pr_ssl_info(int verb) {
1956 	SSL_CIPHER *c;
1957 	SSL_SESSION *s;
1958 	char *proto = "unknown";
1959 	int ssl_version;
1960 
1961 	if (verb) {}
1962 
1963 	if (ssl == NULL) {
1964 		return;
1965 	}
1966 	c = SSL_get_current_cipher(ssl);
1967 	s = SSL_get_session(ssl);
1968 
1969 	if (s) {
1970 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
1971 		ssl_version = SSL_SESSION_get_protocol_version(s);
1972 #else
1973 		ssl_version = s->ssl_version;
1974 #endif
1975 	}
1976 
1977 	if (s == NULL) {
1978 		proto = "nosession";
1979 	} else if (ssl_version == SSL2_VERSION) {
1980 		proto = "SSLv2";
1981 	} else if (ssl_version == SSL3_VERSION) {
1982 		proto = "SSLv3";
1983 	} else if (ssl_version == TLS1_VERSION) {
1984 		proto = "TLSv1";
1985 	}
1986 	if (c != NULL) {
1987 		rfbLog("SSL: ssl_helper[%d]: Cipher: %s %s Proto: %s\n", getpid(),
1988 		    SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c), proto);
1989 	} else {
1990 		rfbLog("SSL: ssl_helper[%d]: Proto: %s\n", getpid(),
1991 		    proto);
1992 	}
1993 }
1994 
ssl_timeout(int sig)1995 static void ssl_timeout (int sig) {
1996 	int i;
1997 	rfbLog("sig: %d, ssl_init[%d] timed out.\n", sig, getpid());
1998 	rfbLog("To increase the SSL initialization timeout use, e.g.:\n");
1999 	rfbLog("   -env SSL_INIT_TIMEOUT=120        (for 120 seconds)\n");
2000 	for (i=0; i < 256; i++) {
2001 		close(i);
2002 	}
2003 	exit(1);
2004 }
2005 
ssl_init(int s_in,int s_out,int skip_vnc_tls,double last_https)2006 static int ssl_init(int s_in, int s_out, int skip_vnc_tls, double last_https) {
2007 	unsigned char *sid = (unsigned char *) "x11vnc SID";
2008 	char *name = NULL;
2009 	int peerport = 0;
2010 	int db = 0, rc, err;
2011 	int ssock = s_in;
2012 	double start = dnow();
2013 	int timeout = 20;
2014 
2015 	if (enc_str != NULL) {
2016 		return 1;
2017 	}
2018 	if (getenv("SSL_DEBUG")) {
2019 		db = atoi(getenv("SSL_DEBUG"));
2020 	}
2021 	usleep(100 * 1000);
2022 	if (getenv("SSL_INIT_TIMEOUT")) {
2023 		timeout = atoi(getenv("SSL_INIT_TIMEOUT"));
2024 	} else if (client_connect != NULL && strstr(client_connect, "repeater")) {
2025 		rfbLog("SSL: ssl_init[%d]: detected 'repeater' in connect string.\n", getpid());
2026 		rfbLog("SSL: setting timeout to 1 hour: -env SSL_INIT_TIMEOUT=3600\n");
2027 		rfbLog("SSL: use that option to set a different timeout value,\n");
2028 		rfbLog("SSL: however note that with Windows UltraVNC repeater it\n");
2029 		rfbLog("SSL: may timeout before your setting due to other reasons.\n");
2030 		timeout = 3600;
2031 	}
2032 
2033 	if (skip_vnc_tls) {
2034 		rfbLog("SSL: ssl_helper[%d]: HTTPS mode, skipping check_vnc_tls_mode()\n",
2035 		    getpid());
2036 	} else if (!check_vnc_tls_mode(s_in, s_out, last_https)) {
2037 		return 0;
2038 	}
2039 	rfbLog("SSL: ssl_init[%d]: %d/%d initialization timeout: %d secs.\n",
2040 	    getpid(), s_in, s_out, timeout);
2041 
2042 	ssl = SSL_new(ctx);
2043 	if (ssl == NULL) {
2044 		fprintf(stderr, "SSL_new failed\n");
2045 		return 0;
2046 	}
2047 	if (db > 1) fprintf(stderr, "ssl_init: 1\n");
2048 
2049 	SSL_set_session_id_context(ssl, sid, strlen((char *)sid));
2050 
2051 	if (s_in == s_out) {
2052 		if (! SSL_set_fd(ssl, ssock)) {
2053 			fprintf(stderr, "SSL_set_fd failed\n");
2054 			return 0;
2055 		}
2056 	} else {
2057 		if (! SSL_set_rfd(ssl, s_in)) {
2058 			fprintf(stderr, "SSL_set_rfd failed\n");
2059 			return 0;
2060 		}
2061 		if (! SSL_set_wfd(ssl, s_out)) {
2062 			fprintf(stderr, "SSL_set_wfd failed\n");
2063 			return 0;
2064 		}
2065 	}
2066 	if (db > 1) fprintf(stderr, "ssl_init: 2\n");
2067 
2068 	if (ssl_client_mode) {
2069 		SSL_set_connect_state(ssl);
2070 	} else {
2071 		SSL_set_accept_state(ssl);
2072 	}
2073 
2074 	if (db > 1) fprintf(stderr, "ssl_init: 3\n");
2075 
2076 	name = get_remote_host(ssock);
2077 	peerport = get_remote_port(ssock);
2078 
2079 	if (!strcmp(name, "0.0.0.0") && openssl_last_ip != NULL) {
2080 		name = strdup(openssl_last_ip);
2081 	}
2082 
2083 	if (db > 1) fprintf(stderr, "ssl_init: 4\n");
2084 
2085 	while (1) {
2086 
2087 		signal(SIGALRM, ssl_timeout);
2088 		alarm(timeout);
2089 
2090 		if (ssl_client_mode) {
2091 			if (db) fprintf(stderr, "calling SSL_connect...\n");
2092 			rc = SSL_connect(ssl);
2093 		} else {
2094 			if (db) fprintf(stderr, "calling SSL_accept...\n");
2095 			rc = SSL_accept(ssl);
2096 		}
2097 		err = SSL_get_error(ssl, rc);
2098 
2099 		alarm(0);
2100 		signal(SIGALRM, SIG_DFL);
2101 
2102 		if (ssl_client_mode) {
2103 			if (db) fprintf(stderr, "SSL_connect %d/%d\n", rc, err);
2104 		} else {
2105 			if (db) fprintf(stderr, "SSL_accept %d/%d\n", rc, err);
2106 		}
2107 		if (err == SSL_ERROR_NONE) {
2108 			break;
2109 		} else if (err == SSL_ERROR_WANT_READ) {
2110 
2111 			if (db) fprintf(stderr, "got SSL_ERROR_WANT_READ\n");
2112 			rfbLog("SSL: ssl_helper[%d]: %s() failed for: %s:%d 1\n",
2113 			    getpid(), ssl_client_mode ? "SSL_connect" : "SSL_accept", name, peerport);
2114 			pr_ssl_info(1);
2115 			return 0;
2116 
2117 		} else if (err == SSL_ERROR_WANT_WRITE) {
2118 
2119 			if (db) fprintf(stderr, "got SSL_ERROR_WANT_WRITE\n");
2120 			rfbLog("SSL: ssl_helper[%d]: %s() failed for: %s:%d 2\n",
2121 			    getpid(), ssl_client_mode ? "SSL_connect" : "SSL_accept", name, peerport);
2122 			pr_ssl_info(1);
2123 			return 0;
2124 
2125 		} else if (err == SSL_ERROR_SYSCALL) {
2126 
2127 			if (db) fprintf(stderr, "got SSL_ERROR_SYSCALL\n");
2128 			rfbLog("SSL: ssl_helper[%d]: %s() failed for: %s:%d 3\n",
2129 			    getpid(), ssl_client_mode ? "SSL_connect" : "SSL_accept", name, peerport);
2130 			pr_ssl_info(1);
2131 			return 0;
2132 
2133 		} else if (err == SSL_ERROR_ZERO_RETURN) {
2134 
2135 			if (db) fprintf(stderr, "got SSL_ERROR_ZERO_RETURN\n");
2136 			rfbLog("SSL: ssl_helper[%d]: %s() failed for: %s:%d 4\n",
2137 			    getpid(), ssl_client_mode ? "SSL_connect" : "SSL_accept", name, peerport);
2138 			pr_ssl_info(1);
2139 			return 0;
2140 
2141 		} else if (rc < 0) {
2142 			unsigned long err;
2143 			int cnt = 0;
2144 
2145 			rfbLog("SSL: ssl_helper[%d]: %s() *FATAL: %d SSL FAILED\n",
2146 			    getpid(), ssl_client_mode ? "SSL_connect" : "SSL_accept", rc);
2147 			while ((err = ERR_get_error()) != 0) {
2148 				rfbLog("SSL: %s\n", ERR_error_string(err, NULL));
2149 				if (cnt++ > 100) {
2150 					break;
2151 				}
2152 			}
2153 			pr_ssl_info(1);
2154 			return 0;
2155 
2156 		} else if (dnow() > start + 3.0) {
2157 
2158 			rfbLog("SSL: ssl_helper[%d]: timeout looping %s() "
2159 			    "fatal.\n", getpid(), ssl_client_mode ? "SSL_connect" : "SSL_accept");
2160 			pr_ssl_info(1);
2161 			return 0;
2162 
2163 		} else {
2164 			BIO *bio = SSL_get_rbio(ssl);
2165 			if (bio == NULL) {
2166 				rfbLog("SSL: ssl_helper[%d]: ssl BIO is null. "
2167 				    "fatal.\n", getpid());
2168 				pr_ssl_info(1);
2169 				return 0;
2170 			}
2171 			if (BIO_eof(bio)) {
2172 				rfbLog("SSL: ssl_helper[%d]: ssl BIO is EOF. "
2173 				    "fatal.\n", getpid());
2174 				pr_ssl_info(1);
2175 				return 0;
2176 			}
2177 		}
2178 		usleep(10 * 1000);
2179 	}
2180 
2181 	if (ssl_client_mode) {
2182 		rfbLog("SSL: ssl_helper[%d]: SSL_connect() succeeded for: %s:%d\n", getpid(), name, peerport);
2183 	} else {
2184 		rfbLog("SSL: ssl_helper[%d]: SSL_accept() succeeded for: %s:%d\n", getpid(), name, peerport);
2185 	}
2186 
2187 	pr_ssl_info(0);
2188 
2189 	if (SSL_get_verify_result(ssl) == X509_V_OK) {
2190 		X509 *x;
2191 		FILE *cr = NULL;
2192 		if (certret != NULL) {
2193 			cr = fopen(certret, "w");
2194 		}
2195 
2196 		x = SSL_get_peer_certificate(ssl);
2197 		if (x == NULL) {
2198 			rfbLog("SSL: ssl_helper[%d]: accepted client %s x509 peer cert is null\n", getpid(), name);
2199 			if (cr != NULL) {
2200 				fprintf(cr, "NOCERT\n");
2201 				fclose(cr);
2202 			}
2203 		} else {
2204 			rfbLog("SSL: ssl_helper[%d]: accepted client %s x509 cert is:\n", getpid(), name);
2205 #if HAVE_X509_PRINT_EX_FP
2206 			X509_print_ex_fp(stderr, x, 0, XN_FLAG_MULTILINE);
2207 #endif
2208 			if (cr != NULL) {
2209 #if HAVE_X509_PRINT_EX_FP
2210 				X509_print_ex_fp(cr, x, 0, XN_FLAG_MULTILINE);
2211 #else
2212 				rfbLog("** not compiled with libssl X509_print_ex_fp() function **\n");
2213 				if (users_list && strstr(users_list, "sslpeer=")) {
2214 					rfbLog("** -users sslpeer= will not work! **\n");
2215 				}
2216 #endif
2217 				fclose(cr);
2218 			}
2219 		}
2220 	}
2221 	free(name);
2222 
2223 	return 1;
2224 }
2225 
2226 static void symmetric_encryption_xfer(int csock, int s_in, int s_out);
2227 
ssl_xfer(int csock,int s_in,int s_out,int is_https)2228 static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
2229 	int dbxfer = 0, db = 0, check_pending, fdmax, nfd, n, i, err;
2230 	char cbuf[ABSIZE], sbuf[ABSIZE];
2231 	int  cptr, sptr, c_rd, c_wr, s_rd, s_wr;
2232 	fd_set rd, wr;
2233 	struct timeval tv;
2234 	int ssock, cnt = 0, ndata = 0;
2235 
2236 	/*
2237 	 * we want to switch to a longer timeout for long term VNC
2238 	 * connections (in case the network is not working for periods of
2239 	 * time), but we also want the timeout shorter at the beginning
2240 	 * in case the client went away.
2241 	 */
2242 	double start, now;
2243 	int tv_https_early = 60;
2244 	int tv_https_later = 20;
2245 	int tv_vnc_early = 40;
2246 	int tv_vnc_later = 43200;	/* was 300, stunnel: 43200 */
2247 	int tv_cutover = 70;
2248 	int tv_closing = 60;
2249 	int tv_use;
2250 
2251 	if (dbxfer) {
2252 		raw_xfer(csock, s_in, s_out);
2253 		return;
2254 	}
2255 	if (enc_str != NULL) {
2256 		if (!strcmp(enc_str, "none")) {
2257 			usleep(250*1000);
2258 			rfbLog("doing '-enc none' raw transfer (no encryption)\n");
2259 			raw_xfer(csock, s_in, s_out);
2260 		} else {
2261 			symmetric_encryption_xfer(csock, s_in, s_out);
2262 		}
2263 		return;
2264 	}
2265 
2266 	if (getenv("SSL_DEBUG")) {
2267 		db = atoi(getenv("SSL_DEBUG"));
2268 	}
2269 
2270 	if (db) fprintf(stderr, "ssl_xfer begin\n");
2271 
2272 	start = dnow();
2273 	if (is_https) {
2274 		tv_use = tv_https_early;
2275 	} else {
2276 		tv_use = tv_vnc_early;
2277 	}
2278 
2279 
2280 	/*
2281 	 * csock: clear text socket with libvncserver.    "C"
2282 	 * ssock: ssl data socket with remote vnc viewer. "S"
2283 	 *
2284 	 * to cover inetd mode, we have s_in and s_out, but in non-inetd
2285 	 * mode they both ssock.
2286 	 *
2287 	 * cbuf[] is data from csock that we have read but not passed on to ssl
2288 	 * sbuf[] is data from ssl that we have read but not passed on to csock
2289 	 */
2290 	for (i=0; i<ABSIZE; i++) {
2291 		cbuf[i] = '\0';
2292 		sbuf[i] = '\0';
2293 	}
2294 
2295 	if (s_out > s_in) {
2296 		ssock = s_out;
2297 	} else {
2298 		ssock = s_in;
2299 	}
2300 
2301 	if (csock > ssock) {
2302 		fdmax = csock;
2303 	} else {
2304 		fdmax = ssock;
2305 	}
2306 
2307 	c_rd = 1;	/* clear text (libvncserver) socket open for reading */
2308 	c_wr = 1;	/* clear text (libvncserver) socket open for writing */
2309 	s_rd = 1;	/* ssl data (remote client)  socket open for reading */
2310 	s_wr = 1;	/* ssl data (remote client)  socket open for writing */
2311 
2312 	cptr = 0;	/* offsets into ABSIZE buffers */
2313 	sptr = 0;
2314 
2315 	if (vencrypt_selected > 0 || anontls_selected > 0) {
2316 		char tmp[16];
2317 		/* read and discard the extra RFB version */
2318 		memset(tmp, 0, sizeof(tmp));
2319 		read(csock, tmp, 12);
2320 		if (0) fprintf(stderr, "extra: %s\n", tmp);
2321 	}
2322 
2323 	while (1) {
2324 		int c_to_s, s_to_c, closing;
2325 
2326 		if ( s_wr && (c_rd || cptr > 0) ) {
2327 			/*
2328 			 * S is writable and
2329 			 * C is readable or some cbuf data remaining
2330 			 */
2331 			c_to_s = 1;
2332 		} else {
2333 			c_to_s = 0;
2334 		}
2335 
2336 		if ( c_wr && (s_rd || sptr > 0) ) {
2337 			/*
2338 			 * C is writable and
2339 			 * S is readable or some sbuf data remaining
2340 			 */
2341 			s_to_c = 1;
2342 		} else {
2343 			s_to_c = 0;
2344 		}
2345 
2346 		if (! c_to_s && ! s_to_c) {
2347 			/*
2348 			 * nothing can be sent either direction.
2349 			 * break out of the loop to finish all work.
2350 			 */
2351 			break;
2352 		}
2353 		cnt++;
2354 
2355 		/* set up the fd sets for the two sockets for read & write: */
2356 
2357 		FD_ZERO(&rd);
2358 
2359 		if (c_rd && cptr < ABSIZE) {
2360 			/* we could read more from C since cbuf is not full */
2361 			FD_SET(csock, &rd);
2362 		}
2363 		if (s_rd) {
2364 			/*
2365 			 * we could read more from S since sbuf not full,
2366 			 * OR ssl is waiting for more BIO to be able to
2367 			 * read and we have some C data still buffered.
2368 			 */
2369 			if (sptr < ABSIZE || (cptr > 0 && SSL_want_read(ssl))) {
2370 				FD_SET(s_in, &rd);
2371 			}
2372 		}
2373 
2374 		FD_ZERO(&wr);
2375 
2376 		if (c_wr && sptr > 0) {
2377 			/* we could write more to C since sbuf is not empty */
2378 			FD_SET(csock, &wr);
2379 		}
2380 		if (s_wr) {
2381 			/*
2382 			 * we could write more to S since cbuf not empty,
2383 			 * OR ssl is waiting for more BIO to be able
2384 			 * write and we haven't filled up sbuf yet.
2385 			 */
2386 			if (cptr > 0 || (sptr < ABSIZE && SSL_want_write(ssl))) {
2387 				FD_SET(s_out, &wr);
2388 			}
2389 		}
2390 
2391 		now = dnow();
2392 		if (tv_cutover && now > start + tv_cutover) {
2393 			rfbLog("SSL: ssl_xfer[%d]: tv_cutover: %d\n", getpid(),
2394 			    tv_cutover);
2395 			tv_cutover = 0;
2396 			if (is_https) {
2397 				tv_use = tv_https_later;
2398 			} else {
2399 				tv_use = tv_vnc_later;
2400 			}
2401 			/* try to clean out some zombies if we can. */
2402 			ssl_helper_pid(0, -2);
2403 		}
2404 		if (ssl_timeout_secs > 0) {
2405 			tv_use = ssl_timeout_secs;
2406 		}
2407 
2408 		if ( (s_rd && c_rd) || cptr || sptr) {
2409 			closing = 0;
2410 		} else {
2411 			closing = 1;
2412 			tv_use = tv_closing;
2413 		}
2414 
2415 		tv.tv_sec  = tv_use;
2416 		tv.tv_usec = 0;
2417 
2418 		/*  do the select, repeat if interrupted */
2419 		do {
2420 			if (ssl_timeout_secs == 0) {
2421 				nfd = select(fdmax+1, &rd, &wr, NULL, NULL);
2422 			} else {
2423 				nfd = select(fdmax+1, &rd, &wr, NULL, &tv);
2424 			}
2425 		} while (nfd < 0 && errno == EINTR);
2426 
2427 		if (db > 1) fprintf(stderr, "nfd: %d\n", nfd);
2428 
2429 if (0) fprintf(stderr, "nfd[%d]: %d  w/r csock: %d %d s_in: %d %d\n", getpid(), nfd, FD_ISSET(csock, &wr), FD_ISSET(csock, &rd), FD_ISSET(s_out, &wr), FD_ISSET(s_in, &rd));
2430 
2431 		if (nfd < 0) {
2432 			rfbLog("SSL: ssl_xfer[%d]: select error: %d\n", getpid(), nfd);
2433 			perror("select");
2434 			/* connection finished */
2435 			goto done;
2436 		}
2437 
2438 		if (nfd == 0) {
2439 			if (!closing && tv_cutover && ndata > 25000) {
2440 				static int cn = 0;
2441 				/* probably ok, early windows iconify */
2442 				if (cn++ < 2) {
2443 					rfbLog("SSL: ssl_xfer[%d]: early time"
2444 					    "out: %d\n", getpid(), ndata);
2445 				}
2446 				continue;
2447 			}
2448 			rfbLog("SSL: ssl_xfer[%d]: connection timedout. %d  tv_use: %d\n",
2449 			    getpid(), ndata, tv_use);
2450 			/* connection finished */
2451 			goto done;
2452 		}
2453 
2454 		/* used to see if SSL_pending() should be checked: */
2455 		check_pending = 0;
2456 /* AUDIT */
2457 
2458 		if (c_wr && FD_ISSET(csock, &wr)) {
2459 
2460 			/* try to write some of our sbuf to C: */
2461 			n = write(csock, sbuf, sptr);
2462 
2463 			if (n < 0) {
2464 				if (errno != EINTR) {
2465 					/* connection finished */
2466 					goto done;
2467 				}
2468 				/* proceed */
2469 			} else if (n == 0) {
2470 				/* connection finished XXX double check */
2471 				goto done;
2472 			} else {
2473 				/* shift over the data in sbuf by n */
2474 				memmove(sbuf, sbuf + n, sptr - n);
2475 				if (sptr == ABSIZE) {
2476 					check_pending = 1;
2477 				}
2478 				sptr -= n;
2479 
2480 				if (! s_rd && sptr == 0) {
2481 					/* finished sending last of sbuf */
2482 					shutdown(csock, SHUT_WR);
2483 					c_wr = 0;
2484 				}
2485 				ndata += n;
2486 			}
2487 		}
2488 
2489 		if (s_wr) {
2490 			if ((cptr > 0 && FD_ISSET(s_out, &wr)) ||
2491 			    (SSL_want_read(ssl) && FD_ISSET(s_in, &rd))) {
2492 
2493 				/* try to write some of our cbuf to S: */
2494 
2495 				n = SSL_write(ssl, cbuf, cptr);
2496 				err = SSL_get_error(ssl, n);
2497 
2498 				if (err == SSL_ERROR_NONE) {
2499 					/* shift over the data in cbuf by n */
2500 					memmove(cbuf, cbuf + n, cptr - n);
2501 					cptr -= n;
2502 
2503 					if (! c_rd && cptr == 0 && s_wr) {
2504 						/* finished sending last cbuf */
2505 						SSL_shutdown(ssl);
2506 						s_wr = 0;
2507 					}
2508 					ndata += n;
2509 
2510 				} else if (err == SSL_ERROR_WANT_WRITE
2511 					|| err == SSL_ERROR_WANT_READ
2512 					|| err == SSL_ERROR_WANT_X509_LOOKUP) {
2513 
2514 						;	/* proceed */
2515 
2516 				} else if (err == SSL_ERROR_SYSCALL) {
2517 					if (n < 0 && errno != EINTR) {
2518 						/* connection finished */
2519 						goto done;
2520 					}
2521 					/* proceed */
2522 				} else if (err == SSL_ERROR_ZERO_RETURN) {
2523 					/* S finished */
2524 					s_rd = 0;
2525 					s_wr = 0;
2526 				} else if (err == SSL_ERROR_SSL) {
2527 					/* connection finished */
2528 					goto done;
2529 				}
2530 			}
2531 		}
2532 
2533 		if (c_rd && FD_ISSET(csock, &rd)) {
2534 
2535 
2536 			/* try to read some data from C into our cbuf */
2537 
2538 			n = read(csock, cbuf + cptr, ABSIZE - cptr);
2539 
2540 			if (n < 0) {
2541 				if (errno != EINTR) {
2542 					/* connection finished */
2543 					goto done;
2544 				}
2545 				/* proceed */
2546 			} else if (n == 0) {
2547 				/* C is EOF */
2548 				c_rd = 0;
2549 				if (cptr == 0 && s_wr) {
2550 					/* and no more in cbuf to send */
2551 					SSL_shutdown(ssl);
2552 					s_wr = 0;
2553 				}
2554 			} else {
2555 				/* good */
2556 
2557 				cptr += n;
2558 				ndata += n;
2559 			}
2560 		}
2561 
2562 		if (s_rd) {
2563 			if ((sptr < ABSIZE && FD_ISSET(s_in, &rd)) ||
2564 			    (SSL_want_write(ssl) && FD_ISSET(s_out, &wr)) ||
2565 			    (check_pending && SSL_pending(ssl))) {
2566 
2567 				/* try to read some data from S into our sbuf */
2568 
2569 				n = SSL_read(ssl, sbuf + sptr, ABSIZE - sptr);
2570 				err = SSL_get_error(ssl, n);
2571 
2572 				if (err == SSL_ERROR_NONE) {
2573 					/* good */
2574 
2575 					sptr += n;
2576 					ndata += n;
2577 
2578 				} else if (err == SSL_ERROR_WANT_WRITE
2579 					|| err == SSL_ERROR_WANT_READ
2580 					|| err == SSL_ERROR_WANT_X509_LOOKUP) {
2581 
2582 						;	/* proceed */
2583 
2584 				} else if (err == SSL_ERROR_SYSCALL) {
2585 					if (n < 0) {
2586 						if(errno != EINTR) {
2587 							/* connection finished */
2588 							goto done;
2589 						}
2590 						/* proceed */
2591 					} else {
2592 						/* S finished */
2593 						s_rd = 0;
2594 						s_wr = 0;
2595 					}
2596 				} else if (err == SSL_ERROR_ZERO_RETURN) {
2597 					/* S is EOF */
2598 					s_rd = 0;
2599 					if (cptr == 0 && s_wr) {
2600 						/* and no more in cbuf to send */
2601 						SSL_shutdown(ssl);
2602 						s_wr = 0;
2603 					}
2604 					if (sptr == 0 && c_wr) {
2605 						/* and no more in sbuf to send */
2606 						shutdown(csock, SHUT_WR);
2607 						c_wr = 0;
2608 					}
2609 				} else if (err == SSL_ERROR_SSL) {
2610 					/* connection finished */
2611 					goto done;
2612 				}
2613 			}
2614 		}
2615 	}
2616 
2617 	done:
2618 	rfbLog("SSL: ssl_xfer[%d]: closing sockets %d, %d, %d\n",
2619 			    getpid(), csock, s_in, s_out);
2620 	close(csock);
2621 	close(s_in);
2622 	close(s_out);
2623 	return;
2624 }
2625 
2626 #define MSZ 4096
init_prng(void)2627 static void init_prng(void) {
2628 	int db = 0, bytes, ubytes, fd;
2629 	char file[MSZ], dtmp[100];
2630 	unsigned int sr;
2631 
2632 	RAND_file_name(file, MSZ);
2633 
2634 	rfbLog("RAND_file_name: %s\n", file);
2635 
2636 	bytes = RAND_load_file(file, -1);
2637 	if (db) fprintf(stderr, "bytes read: %d\n", bytes);
2638 
2639 	ubytes = RAND_load_file("/dev/urandom", 64);
2640 	bytes += ubytes;
2641 	if (db) fprintf(stderr, "bytes read: %d / %d\n", bytes, ubytes);
2642 
2643 	/* mix in more predictable stuff as well for fallback */
2644 	sprintf(dtmp, "/tmp/p%.8f.XXXXXX", dnow());
2645 	fd = mkstemp(dtmp);
2646 	RAND_add(dtmp, strlen(dtmp), 0);
2647 	if (fd >= 0) {
2648 		close(fd);
2649 		unlink(dtmp);
2650 	}
2651 	sprintf(dtmp, "%d-%.8f", (int) getpid(), dnow());
2652 	RAND_add(dtmp, strlen(dtmp), 0);
2653 
2654 	if (!RAND_status()) {
2655 		ubytes = -1;
2656 		rfbLog("calling RAND_poll()\n");
2657 		RAND_poll();
2658 	}
2659 
2660 	RAND_bytes((unsigned char *)&sr, 4);
2661 	srand(sr);
2662 
2663 	if (bytes > 0) {
2664 		if (! quiet) {
2665 			rfbLog("initialized PRNG with %d random bytes.\n",
2666 			    bytes);
2667 		}
2668 		if (ubytes > 32 && rnow() < 0.25) {
2669 			RAND_write_file(file);
2670 		}
2671 		return;
2672 	}
2673 
2674 	bytes += RAND_load_file("/dev/random", 8);
2675 	if (db) fprintf(stderr, "bytes read: %d\n", bytes);
2676 	RAND_poll();
2677 
2678 	if (! quiet) {
2679 		rfbLog("initialized PRNG with %d random bytes.\n", bytes);
2680 	}
2681 }
2682 #endif	/* FORK_OK */
2683 #endif	/* LIBVNCSERVER_HAVE_LIBSSL or HAVE_LIBSSL  */
2684 
check_openssl(void)2685 void check_openssl(void) {
2686 	fd_set fds;
2687 	struct timeval tv;
2688 	int nfds, nmax = openssl_sock;
2689 	static time_t last_waitall = 0;
2690 	static double last_check = 0.0;
2691 	double now;
2692 
2693 	if (! use_openssl) {
2694 		return;
2695 	}
2696 
2697 	if (time(NULL) > last_waitall + 120) {
2698 		last_waitall = time(NULL);
2699 		ssl_helper_pid(0, -2);	/* waitall */
2700 	}
2701 
2702 	if (openssl_sock < 0 && openssl_sock6 < 0) {
2703 		return;
2704 	}
2705 
2706 	now = dnow();
2707 	if (now < last_check + 0.5) {
2708 		return;
2709 	}
2710 	last_check = now;
2711 
2712 	FD_ZERO(&fds);
2713 	if (openssl_sock >= 0) {
2714 		FD_SET(openssl_sock, &fds);
2715 	}
2716 	if (openssl_sock6 >= 0) {
2717 		FD_SET(openssl_sock6, &fds);
2718 		if (openssl_sock6 > openssl_sock) {
2719 			nmax = openssl_sock6;
2720 		}
2721 	}
2722 
2723 	tv.tv_sec = 0;
2724 	tv.tv_usec = 0;
2725 
2726 	nfds = select(nmax+1, &fds, NULL, NULL, &tv);
2727 
2728 	if (nfds <= 0) {
2729 		return;
2730 	}
2731 
2732 	if (openssl_sock >= 0 && FD_ISSET(openssl_sock, &fds)) {
2733 		rfbLog("SSL: accept_openssl(OPENSSL_VNC)\n");
2734 		accept_openssl(OPENSSL_VNC, -1);
2735 	}
2736 	if (openssl_sock6 >= 0 && FD_ISSET(openssl_sock6, &fds)) {
2737 		rfbLog("SSL: accept_openssl(OPENSSL_VNC6)\n");
2738 		accept_openssl(OPENSSL_VNC6, -1);
2739 	}
2740 }
2741 
check_https(void)2742 void check_https(void) {
2743 	fd_set fds;
2744 	struct timeval tv;
2745 	int nfds, nmax = https_sock;
2746 	static double last_check = 0.0;
2747 	double now;
2748 
2749 	if (! use_openssl || (https_sock < 0 && https_sock6 < 0)) {
2750 		return;
2751 	}
2752 
2753 	now = dnow();
2754 	if (now < last_check + 0.5) {
2755 		return;
2756 	}
2757 	last_check = now;
2758 
2759 	FD_ZERO(&fds);
2760 	if (https_sock >= 0) {
2761 		FD_SET(https_sock, &fds);
2762 	}
2763 	if (https_sock6 >= 0) {
2764 		FD_SET(https_sock6, &fds);
2765 		if (https_sock6 > https_sock) {
2766 			nmax = https_sock6;
2767 		}
2768 	}
2769 
2770 	tv.tv_sec = 0;
2771 	tv.tv_usec = 0;
2772 
2773 	nfds = select(nmax+1, &fds, NULL, NULL, &tv);
2774 
2775 	if (nfds <= 0) {
2776 		return;
2777 	}
2778 
2779 	if (https_sock >= 0 && FD_ISSET(https_sock, &fds)) {
2780 		rfbLog("SSL: accept_openssl(OPENSSL_HTTPS)\n");
2781 		accept_openssl(OPENSSL_HTTPS, -1);
2782 	}
2783 	if (https_sock6 >= 0 && FD_ISSET(https_sock6, &fds)) {
2784 		rfbLog("SSL: accept_openssl(OPENSSL_HTTPS6)\n");
2785 		accept_openssl(OPENSSL_HTTPS6, -1);
2786 	}
2787 }
2788 
openssl_port(int restart)2789 void openssl_port(int restart) {
2790 	int sock = -1, shutdown = 0;
2791 	static int port = -1;
2792 	static in_addr_t iface = INADDR_ANY;
2793 	int db = 0, fd6 = -1;
2794 
2795 	if (! screen) {
2796 		rfbLog("openssl_port: no screen!\n");
2797 		clean_up_exit(1);
2798 	}
2799 	if (inetd) {
2800 		ssl_initialized = 1;
2801 		return;
2802 	}
2803 
2804 	if (ipv6_listen && screen->port <= 0) {
2805 		if (got_rfbport) {
2806 			screen->port = got_rfbport_val;
2807 		} else {
2808 			int ap = 5900;
2809 			if (auto_port > 0) {
2810 				ap = auto_port;
2811 			}
2812 			screen->port = find_free_port6(ap, ap+200);
2813 		}
2814 		rfbLog("openssl_port: reset port from 0 => %d\n", screen->port);
2815 	}
2816 
2817 	if (restart) {
2818 		port = screen->port;
2819 	} else if (screen->listenSock > -1 && screen->port > 0) {
2820 		port = screen->port;
2821 		shutdown = 1;
2822 	} else if (ipv6_listen && screen->port > 0) {
2823 		port = screen->port;
2824 	} else if (screen->port == 0) {
2825 		port = screen->port;
2826 	}
2827 
2828 	iface = screen->listenInterface;
2829 
2830 	if (shutdown) {
2831 		if (db) fprintf(stderr, "shutting down %d/%d\n",
2832 		    port, screen->listenSock);
2833 #if LIBVNCSERVER_HAS_SHUTDOWNSOCKETS
2834 		rfbShutdownSockets(screen);
2835 #endif
2836 	}
2837 
2838 	if (openssl_sock >= 0) {
2839 		close(openssl_sock);
2840 		openssl_sock = -1;
2841 	}
2842 	if (openssl_sock6 >= 0) {
2843 		close(openssl_sock6);
2844 		openssl_sock6 = -1;
2845 	}
2846 
2847 	if (port < 0) {
2848 		rfbLog("openssl_port: could not obtain listening port %d\n", port);
2849 		if (!got_rfbport && !got_ipv6_listen) {
2850 			rfbLog("openssl_port: if this system is IPv6-only, use the -6 option\n");
2851 		}
2852 		clean_up_exit(1);
2853 	} else if (port == 0) {
2854 		/* no listen case, i.e. -connect */
2855 		sock = -1;
2856 	} else {
2857 		sock = listen_tcp(port, iface, 0);
2858 		if (ipv6_listen) {
2859 			fd6 = listen6(port);
2860 		} else if (!got_rfbport && !got_ipv6_listen) {
2861 			if (sock < 0) {
2862 				rfbLog("openssl_port: if this system is IPv6-only, use the -6 option\n");
2863 			}
2864 		}
2865 		if (sock < 0) {
2866 			if (fd6 < 0) {
2867 				rfbLog("openssl_port: could not reopen port %d\n", port);
2868 				if (!restart) {
2869 					clean_up_exit(1);
2870 				}
2871 			} else {
2872 				rfbLog("openssl_port: Info: listening on IPv6 only.\n");
2873 			}
2874 		}
2875 	}
2876 	rfbLog("openssl_port: listen on port/sock %d/%d\n", port, sock);
2877 	if (ipv6_listen && port > 0) {
2878 		if (fd6 < 0) {
2879 			fd6 = listen6(port);
2880 		}
2881 		if (fd6 < 0) {
2882 			ipv6_listen = 0;
2883 		} else {
2884 			rfbLog("openssl_port: listen on port/sock %d/%d (ipv6)\n",
2885 			    port, fd6);
2886 			openssl_sock6 = fd6;
2887 		}
2888 	}
2889 	if (!quiet && sock >=0) {
2890 		announce(port, 1, NULL);
2891 	}
2892 	openssl_sock = sock;
2893 	openssl_port_num = port;
2894 
2895 	ssl_initialized = 1;
2896 }
2897 
https_port(int restart)2898 void https_port(int restart) {
2899 	int sock, fd6 = -1;
2900 	static int port = 0;
2901 	static in_addr_t iface = INADDR_ANY;
2902 
2903 	/* as openssl_port above: open a listening socket for pure https: */
2904 	if (https_port_num < 0) {
2905 		return;
2906 	}
2907 	if (! screen) {
2908 		rfbLog("https_port: no screen!\n");
2909 		clean_up_exit(1);
2910 	}
2911 	if (! screen->httpDir) {
2912 		return;
2913 	}
2914 	if (screen->listenInterface) {
2915 		iface = screen->listenInterface;
2916 	}
2917 
2918 	if (https_port_num == 0) {
2919 		https_port_num = find_free_port(5801, 5851);
2920 	}
2921 	if (ipv6_listen && https_port_num <= 0) {
2922 		https_port_num = find_free_port6(5801, 5851);
2923 	}
2924 	if (https_port_num <= 0) {
2925 		rfbLog("https_port: could not find port %d\n", https_port_num);
2926 		clean_up_exit(1);
2927 	}
2928 	port = https_port_num;
2929 
2930 	if (port <= 0) {
2931 		rfbLog("https_port: could not obtain listening port %d\n", port);
2932 		if (!restart) {
2933 			clean_up_exit(1);
2934 		} else {
2935 			return;
2936 		}
2937 	}
2938 	if (https_sock >= 0) {
2939 		close(https_sock);
2940 		https_sock = -1;
2941 	}
2942 	if (https_sock6 >= 0) {
2943 		close(https_sock6);
2944 		https_sock6 = -1;
2945 	}
2946 	sock = listen_tcp(port, iface, 0);
2947 	if (sock < 0) {
2948 		rfbLog("https_port: could not open port %d\n", port);
2949 		if (ipv6_listen) {
2950 			fd6 = listen6(port);
2951 		}
2952 		if (fd6 < 0) {
2953 			if (!restart) {
2954 				clean_up_exit(1);
2955 			}
2956 		}
2957 		rfbLog("https_port: trying IPv6 only mode.\n");
2958 	}
2959 	rfbLog("https_port: listen on port/sock %d/%d\n", port, sock);
2960 	https_sock = sock;
2961 
2962 	if (ipv6_listen) {
2963 		if (fd6 < 0) {
2964 			fd6 = listen6(port);
2965 		}
2966 		if (fd6 < 0) {
2967 			;
2968 		} else {
2969 			rfbLog("https_port: listen on port/sock %d/%d (ipv6)\n",
2970 			    port, fd6);
2971 			https_sock6 = fd6;
2972 		}
2973 		if (fd6 < 0 && https_sock < 0) {
2974 			rfbLog("https_port: could not listen on either IPv4 or IPv6.\n");
2975 			if (!restart) {
2976 				clean_up_exit(1);
2977 			}
2978 		}
2979 	}
2980 }
2981 
lose_ram(void)2982 static void lose_ram(void) {
2983 	/*
2984 	 * for a forked child that will be around for a long time
2985 	 * without doing exec().  we really should re-exec, but a pain
2986 	 * to redo all SSL ctx.
2987 	 */
2988 	free_old_fb();
2989 
2990 	free_tiles();
2991 }
2992 
2993 /* utility to keep track of existing helper processes: */
2994 
ssl_helper_pid(pid_t pid,int sock)2995 void ssl_helper_pid(pid_t pid, int sock) {
2996 #	define HPSIZE 256
2997 	static pid_t helpers[HPSIZE];
2998 	static int   sockets[HPSIZE], first = 1;
2999 	int i, empty, set, status;
3000 	static int db = 0;
3001 
3002 	if (first) {
3003 		for (i=0; i < HPSIZE; i++)  {
3004 			helpers[i] = 0;
3005 			sockets[i] = 0;
3006 		}
3007 		if (getenv("SSL_HELPER_PID_DB")) {
3008 			db = 1;
3009 		}
3010 		first = 0;
3011 	}
3012 
3013 
3014 	if (pid == 0) {
3015 		/* killall or waitall */
3016 		for (i=0; i < HPSIZE; i++) {
3017 			if (helpers[i] == 0) {
3018 				sockets[i] = -1;
3019 				continue;
3020 			}
3021 			if (kill(helpers[i], 0) == 0) {
3022 				int kret = -2;
3023 				pid_t wret;
3024 				if (sock != -2) {
3025 					if (sockets[i] >= 0) {
3026 						close(sockets[i]);
3027 					}
3028 					kret = kill(helpers[i], SIGTERM);
3029 					if (kret == 0) {
3030 						usleep(20 * 1000);
3031 					}
3032 				}
3033 
3034 #if LIBVNCSERVER_HAVE_SYS_WAIT_H && HAVE_WAITPID
3035 				wret = waitpid(helpers[i], &status, WNOHANG);
3036 
3037 if (db) fprintf(stderr, "waitpid(%d)\n", helpers[i]);
3038 if (db) fprintf(stderr, "  waitret1=%d\n", wret);
3039 
3040 				if (kret == 0 && wret != helpers[i]) {
3041 					int k;
3042 					for (k=0; k < 10; k++) {
3043 						usleep(100 * 1000);
3044 						wret = waitpid(helpers[i], &status, WNOHANG);
3045 if (db) fprintf(stderr, "  waitret2=%d\n", wret);
3046 						if (wret == helpers[i]) {
3047 							break;
3048 						}
3049 					}
3050 				}
3051 #endif
3052 				if (sock == -2) {
3053 					continue;
3054 				}
3055 			}
3056 			helpers[i] = 0;
3057 			sockets[i] = -1;
3058 		}
3059 		return;
3060 	}
3061 
3062 if (db) fprintf(stderr, "ssl_helper_pid(%d, %d)\n", pid, sock);
3063 
3064 	/* add (or delete for sock == -1) */
3065 	set = 0;
3066 	empty = -1;
3067 	for (i=0; i < HPSIZE; i++) {
3068 		if (helpers[i] == pid) {
3069 			if (sock == -1) {
3070 #if LIBVNCSERVER_HAVE_SYS_WAIT_H && HAVE_WAITPID
3071 				pid_t wret;
3072 				wret = waitpid(helpers[i], &status, WNOHANG);
3073 
3074 if (db) fprintf(stderr, "waitpid(%d) 2\n", helpers[i]);
3075 if (db) fprintf(stderr, "  waitret1=%d\n", wret);
3076 #endif
3077 				helpers[i] = 0;
3078 			}
3079 			sockets[i] = sock;
3080 			set = 1;
3081 		} else if (empty == -1 && helpers[i] == 0) {
3082 			empty = i;
3083 		}
3084 	}
3085 	if (set || sock == -1) {
3086 		return;	/* done */
3087 	}
3088 
3089 	/* now try to store */
3090 	if (empty >= 0) {
3091 		helpers[empty] = pid;
3092 		sockets[empty] = sock;
3093 		return;
3094 	}
3095 	for (i=0; i < HPSIZE; i++) {
3096 		if (helpers[i] == 0) {
3097 			continue;
3098 		}
3099 		/* clear out stale pids: */
3100 		if (kill(helpers[i], 0) != 0) {
3101 			helpers[i] = 0;
3102 			sockets[i] = -1;
3103 
3104 			if (empty == -1) {
3105 				empty = i;
3106 			}
3107 		}
3108 	}
3109 	if (empty >= 0) {
3110 		helpers[empty] = pid;
3111 		sockets[empty] = sock;
3112 	}
3113 }
3114 
is_ssl_readable(int s_in,double last_https,char * last_get,int mode)3115 static int is_ssl_readable(int s_in, double last_https, char *last_get,
3116     int mode) {
3117 	int nfd, db = 0;
3118 	struct timeval tv;
3119 	fd_set rd;
3120 
3121 	if (getenv("ACCEPT_OPENSSL_DEBUG")) {
3122 		db = atoi(getenv("ACCEPT_OPENSSL_DEBUG"));
3123 	}
3124 
3125 	/*
3126 	 * we'll do a select() on s_in for reading.  this is not an
3127 	 * absolute proof that SSL_read is ready (XXX use SSL utility).
3128 	 */
3129 	tv.tv_sec  = 2;
3130 	tv.tv_usec = 0;
3131 
3132 	if (mode == OPENSSL_INETD) {
3133 		/*
3134 		 * https via inetd is icky because x11vnc is restarted
3135 		 * for each socket (and some clients send requests
3136 		 * rapid fire).
3137 		 */
3138 		tv.tv_sec = 4;
3139 	}
3140 
3141 	/*
3142 	 * increase the timeout if we know HTTP traffic has occurred
3143 	 * recently:
3144 	 */
3145 	if (dnow() < last_https + 30.0) {
3146 		tv.tv_sec = 10;
3147 		if (last_get && strstr(last_get, "VncViewer")) {
3148 			tv.tv_sec = 5;
3149 		}
3150 	}
3151 	if (getenv("X11VNC_HTTPS_VS_VNC_TIMEOUT")) {
3152 		tv.tv_sec  = atoi(getenv("X11VNC_HTTPS_VS_VNC_TIMEOUT"));
3153 	}
3154 if (db) fprintf(stderr, "tv_sec: %d - '%s'\n", (int) tv.tv_sec, last_get);
3155 
3156 	FD_ZERO(&rd);
3157 	FD_SET(s_in, &rd);
3158 
3159 	if (db) fprintf(stderr, "is_ssl_readable: begin  select(%d secs) %.6f\n", (int) tv.tv_sec, dnow());
3160 	do {
3161 		nfd = select(s_in+1, &rd, NULL, NULL, &tv);
3162 	} while (nfd < 0 && errno == EINTR);
3163 	if (db) fprintf(stderr, "is_ssl_readable: finish select(%d secs) %.6f\n", (int) tv.tv_sec, dnow());
3164 
3165 	if (db) fprintf(stderr, "https nfd: %d\n", nfd);
3166 
3167 	if (nfd <= 0 || ! FD_ISSET(s_in, &rd)) {
3168 		return 0;
3169 	}
3170 	return 1;
3171 }
3172 
watch_for_http_traffic(char * buf_a,int * n_a,int raw_sock)3173 static int watch_for_http_traffic(char *buf_a, int *n_a, int raw_sock) {
3174 	int is_http, err, n, n2;
3175 	char *buf;
3176 	int db = 0;
3177 	/*
3178 	 * sniff the first couple bytes of the stream and try to see
3179 	 * if it is http or not.  if we read them OK, we must read the
3180 	 * rest of the available data otherwise we may deadlock.
3181 	 * what has been read is returned in buf_a and n_a.
3182 	 * *buf_a is ABSIZE+1 long and zeroed.
3183 	 */
3184 	if (getenv("ACCEPT_OPENSSL_DEBUG")) {
3185 		db = atoi(getenv("ACCEPT_OPENSSL_DEBUG"));
3186 	}
3187 	if (! buf_a || ! n_a) {
3188 		return 0;
3189 	}
3190 
3191 	buf = (char *) calloc((ABSIZE+1), 1);
3192 	*n_a = 0;
3193 
3194 	if (enc_str && !strcmp(enc_str, "none")) {
3195 		n = read(raw_sock, buf, 2);
3196 		err = SSL_ERROR_NONE;
3197 	} else {
3198 #if LIBVNCSERVER_HAVE_LIBSSL || HAVE_LIBSSL
3199 		n = SSL_read(ssl, buf, 2);
3200 		err = SSL_get_error(ssl, n);
3201 #else
3202 		err = n = 0;
3203 		badnews("1 in watch_for_http_traffic");
3204 #endif
3205 	}
3206 
3207 	if (err != SSL_ERROR_NONE || n < 2) {
3208 		if (n > 0) {
3209 			strncpy(buf_a, buf, n);
3210 			*n_a = n;
3211 		}
3212 		if (db) fprintf(stderr, "watch_for_http_traffic ssl err: %d/%d\n", err, n);
3213 		return -1;
3214 	}
3215 
3216 	/* look for GET, HEAD, POST, CONNECT */
3217 	is_http = 0;
3218 	if (!strncmp("GE", buf, 2)) {
3219 		is_http = 1;
3220 	} else if (!strncmp("HE", buf, 2)) {
3221 		is_http = 1;
3222 	} else if (!strncmp("PO", buf, 2)) {
3223 		is_http = 1;
3224 	} else if (!strncmp("CO", buf, 2)) {
3225 		is_http = 1;
3226 	}
3227 	if (db) fprintf(stderr, "watch_for_http_traffic read: '%s' %d\n", buf, n);
3228 
3229 	/*
3230 	 * better read all we can and fwd it along to avoid blocking
3231 	 * in ssl_xfer().
3232 	 */
3233 
3234 	if (enc_str && !strcmp(enc_str, "none")) {
3235 		n2 = read(raw_sock, buf + n, ABSIZE - n);
3236 	} else {
3237 #if LIBVNCSERVER_HAVE_LIBSSL || HAVE_LIBSSL
3238 		n2 = SSL_read(ssl, buf + n, ABSIZE - n);
3239 #else
3240 		n2 = 0;
3241 		badnews("2 in watch_for_http_traffic");
3242 #endif
3243 	}
3244 	if (n2 >= 0) {
3245 		n += n2;
3246 	}
3247 
3248 	*n_a = n;
3249 
3250 	if (db) fprintf(stderr, "watch_for_http_traffic readmore: %d\n", n2);
3251 
3252 	if (n > 0) {
3253 		memcpy(buf_a, buf, n);
3254 	}
3255 	if (db > 1) {
3256 		fprintf(stderr, "watch_for_http_traffic readmore: ");
3257 		write(2, buf_a, *n_a);
3258 		fprintf(stderr, "\n");
3259 	}
3260 	if (db) fprintf(stderr, "watch_for_http_traffic return: %d\n", is_http);
3261 	return is_http;
3262 }
3263 
3264 static int csock_timeout_sock = -1;
3265 
csock_timeout(int sig)3266 static void csock_timeout (int sig) {
3267 	rfbLog("sig: %d, csock_timeout.\n", sig);
3268 	if (csock_timeout_sock >= 0) {
3269 		close(csock_timeout_sock);
3270 		csock_timeout_sock = -1;
3271 	}
3272 }
3273 
check_ssl_access(char * addr)3274 static int check_ssl_access(char *addr) {
3275 	static char *save_allow_once = NULL;
3276 	static time_t time_allow_once = 0;
3277 
3278 	/* due to "Fetch Cert" activities for SSL really need to "allow twice" */
3279 	if (allow_once != NULL) {
3280 		save_allow_once = strdup(allow_once);
3281 		time_allow_once = time(NULL);
3282 	} else if (save_allow_once != NULL) {
3283 		if (getenv("X11VNC_NO_SSL_ALLOW_TWICE")) {
3284 			;
3285 		} else if (time(NULL) < time_allow_once + 30) {
3286 			/* give them 30 secs to check and save the fetched cert. */
3287 			allow_once = save_allow_once;
3288 			rfbLog("SSL: Permitting 30 sec grace period for allowonce.\n");
3289 			rfbLog("SSL: Set X11VNC_NO_SSL_ALLOW_TWICE=1 to disable.\n");
3290 		}
3291 		save_allow_once = NULL;
3292 		time_allow_once = 0;
3293 	}
3294 
3295 	return check_access(addr);
3296 }
3297 
accept_openssl(int mode,int presock)3298 void accept_openssl(int mode, int presock) {
3299 	int sock = -1, listen = -1, cport, csock, vsock;
3300 	int peerport = 0;
3301 	int status, n, i, db = 0;
3302 	struct sockaddr_in addr;
3303 #ifdef __hpux
3304 	int addrlen = sizeof(addr);
3305 #else
3306 	socklen_t addrlen = sizeof(addr);
3307 #endif
3308 	rfbClientPtr client;
3309 	pid_t pid;
3310 	char uniq[] = "_evilrats_";
3311 	char cookie[256], rcookie[256], *name = NULL;
3312 	int vencrypt_sel = 0;
3313 	int anontls_sel = 0;
3314 	char *ipv6_name = NULL;
3315 	static double last_https = 0.0;
3316 	static char last_get[256];
3317 	static int first = 1;
3318 	unsigned char *rb;
3319 
3320 #if !LIBVNCSERVER_HAVE_LIBSSL && !HAVE_LIBSSL
3321 	if (enc_str == NULL || strcmp(enc_str, "none")) {
3322 		badnews("0 accept_openssl");
3323 	}
3324 #endif
3325 
3326 	openssl_last_helper_pid = 0;
3327 
3328 	/* zero buffers for use below. */
3329 	for (i=0; i<256; i++) {
3330 		if (first) {
3331 			last_get[i] = '\0';
3332 		}
3333 		cookie[i]  = '\0';
3334 		rcookie[i] = '\0';
3335 	}
3336 	first = 0;
3337 
3338 	if (getenv("ACCEPT_OPENSSL_DEBUG")) {
3339 		db = atoi(getenv("ACCEPT_OPENSSL_DEBUG"));
3340 	}
3341 
3342 	/* do INETD, VNC, or HTTPS cases (result is client socket or pipe) */
3343 	if (mode == OPENSSL_INETD) {
3344 		ssl_initialized = 1;
3345 
3346 	} else if (mode == OPENSSL_VNC) {
3347 		sock = accept(openssl_sock, (struct sockaddr *)&addr, &addrlen);
3348 		if (sock < 0)  {
3349 			rfbLog("SSL: accept_openssl: accept connection failed\n");
3350 			rfbLogPerror("accept");
3351 			if (ssl_no_fail) {
3352 				clean_up_exit(1);
3353 			}
3354 			return;
3355 		}
3356 		listen = openssl_sock;
3357 
3358 	} else if (mode == OPENSSL_VNC6 || mode == OPENSSL_HTTPS6) {
3359 #if X11VNC_IPV6
3360 		struct sockaddr_in6 a6;
3361 		socklen_t a6len = sizeof(a6);
3362 		int fd = (mode == OPENSSL_VNC6 ? openssl_sock6 : https_sock6);
3363 
3364 		sock = accept(fd, (struct sockaddr *)&a6, &a6len);
3365 		if (sock < 0)  {
3366 			rfbLog("SSL: accept_openssl: accept connection failed\n");
3367 			rfbLogPerror("accept");
3368 			if (ssl_no_fail) {
3369 				clean_up_exit(1);
3370 			}
3371 			return;
3372 		}
3373 		ipv6_name = ipv6_getipaddr((struct sockaddr *)&a6, a6len);
3374 		if (!ipv6_name) ipv6_name = strdup("unknown");
3375 		listen = fd;
3376 #endif
3377 	} else if (mode == OPENSSL_REVERSE) {
3378 		sock = presock;
3379 		if (sock < 0)  {
3380 			rfbLog("SSL: accept_openssl: connection failed\n");
3381 			if (ssl_no_fail) {
3382 				clean_up_exit(1);
3383 			}
3384 			return;
3385 		}
3386 		if (getenv("OPENSSL_REVERSE_DEBUG")) fprintf(stderr, "OPENSSL_REVERSE: ipv6_client_ip_str: %s\n", ipv6_client_ip_str);
3387 		if (ipv6_client_ip_str != NULL) {
3388 			ipv6_name = strdup(ipv6_client_ip_str);
3389 		}
3390 		listen = -1;
3391 
3392 	} else if (mode == OPENSSL_HTTPS) {
3393 		sock = accept(https_sock, (struct sockaddr *)&addr, &addrlen);
3394 		if (sock < 0)  {
3395 			rfbLog("SSL: accept_openssl: accept connection failed\n");
3396 			rfbLogPerror("accept");
3397 			if (ssl_no_fail) {
3398 				clean_up_exit(1);
3399 			}
3400 			return;
3401 		}
3402 		listen = https_sock;
3403 	}
3404 	if (db) fprintf(stderr, "SSL: accept_openssl: sock: %d\n", sock);
3405 
3406 	if (openssl_last_ip) {
3407 		free(openssl_last_ip);
3408 		openssl_last_ip = NULL;
3409 	}
3410 	if (mode == OPENSSL_INETD) {
3411 		openssl_last_ip = get_remote_host(fileno(stdin));
3412 	} else if (mode == OPENSSL_VNC6 || mode == OPENSSL_HTTPS6) {
3413 		openssl_last_ip = ipv6_name;
3414 	} else if (mode == OPENSSL_REVERSE && ipv6_name != NULL) {
3415 		openssl_last_ip = ipv6_name;
3416 	} else {
3417 		openssl_last_ip = get_remote_host(sock);
3418 	}
3419 
3420 	if (!check_ssl_access(openssl_last_ip)) {
3421 		rfbLog("SSL: accept_openssl: denying client %s\n", openssl_last_ip);
3422 		rfbLog("SSL: accept_openssl: does not match -allow or other reason.\n");
3423 		close(sock);
3424 		sock = -1;
3425 		if (ssl_no_fail) {
3426 			clean_up_exit(1);
3427 		}
3428 		return;
3429 	}
3430 
3431 	/* now make a listening socket for child to connect back to us by: */
3432 
3433 	cport = find_free_port(20000, 22000);
3434 	if (! cport && ipv6_listen) {
3435 		rfbLog("SSL: accept_openssl: seeking IPv6 port.\n");
3436 		cport = find_free_port6(20000, 22000);
3437 		rfbLog("SSL: accept_openssl: IPv6 port: %d\n", cport);
3438 	}
3439 	if (! cport) {
3440 		rfbLog("SSL: accept_openssl: could not find open port.\n");
3441 		close(sock);
3442 		if (mode == OPENSSL_INETD || ssl_no_fail) {
3443 			clean_up_exit(1);
3444 		}
3445 		return;
3446 	}
3447 	if (db) fprintf(stderr, "accept_openssl: cport: %d\n", cport);
3448 
3449 	csock = listen_tcp(cport, htonl(INADDR_LOOPBACK), 1);
3450 
3451 	if (csock < 0) {
3452 		rfbLog("SSL: accept_openssl: could not listen on port %d.\n",
3453 		    cport);
3454 		close(sock);
3455 		if (mode == OPENSSL_INETD || ssl_no_fail) {
3456 			clean_up_exit(1);
3457 		}
3458 		return;
3459 	}
3460 	if (db) fprintf(stderr, "accept_openssl: csock: %d\n", csock);
3461 
3462 	fflush(stderr);
3463 
3464 	/*
3465 	 * make a simple cookie to id the child socket, not foolproof
3466 	 * but hard to guess exactly (just worrying about local lusers
3467 	 * here, since we use INADDR_LOOPBACK).
3468 	 */
3469 	rb = (unsigned char *) calloc(6, 1);
3470 #if LIBVNCSERVER_HAVE_LIBSSL || HAVE_LIBSSL
3471 	RAND_bytes(rb, 6);
3472 #endif
3473 	sprintf(cookie, "RB=%d%d%d%d%d%d/%f%f/%p",
3474 	    rb[0], rb[1], rb[2], rb[3], rb[4], rb[5],
3475             dnow() - x11vnc_start, x11vnc_start, (void *)rb);
3476 
3477 	if (mode == OPENSSL_VNC6) {
3478 		name = strdup(ipv6_name);
3479 		peerport = get_remote_port(sock);
3480 	} else if (mode == OPENSSL_REVERSE && ipv6_name != NULL) {
3481 		name = strdup(ipv6_name);
3482 		peerport = get_remote_port(sock);
3483 	} else if (mode != OPENSSL_INETD) {
3484 		name = get_remote_host(sock);
3485 		peerport = get_remote_port(sock);
3486 	} else {
3487 		openssl_last_ip = get_remote_host(fileno(stdin));
3488 		peerport = get_remote_port(fileno(stdin));
3489 		if (openssl_last_ip) {
3490 			name = strdup(openssl_last_ip);
3491 		} else {
3492 			name = strdup("unknown");
3493 		}
3494 	}
3495 	if (name) {
3496 		if (mode == OPENSSL_INETD) {
3497 			rfbLog("SSL: (inetd) spawning helper process "
3498 			    "to handle: %s:%d\n", name, peerport);
3499 		} else {
3500 			rfbLog("SSL: spawning helper process to handle: "
3501 			    "%s:%d\n", name, peerport);
3502 		}
3503 		free(name);
3504 		name = NULL;
3505 	}
3506 
3507 	if (certret) {
3508 		free(certret);
3509 	}
3510 	if (certret_str) {
3511 		free(certret_str);
3512 		certret_str = NULL;
3513 	}
3514 	certret = strdup("/tmp/x11vnc-certret.XXXXXX");
3515 	omode = umask(077);
3516 	certret_fd = mkstemp(certret);
3517 	umask(omode);
3518 	if (certret_fd < 0) {
3519 		free(certret);
3520 		certret = NULL;
3521 		certret_fd = -1;
3522 	}
3523 
3524 	if (dhret) {
3525 		free(dhret);
3526 	}
3527 	if (dhret_str) {
3528 		free(dhret_str);
3529 		dhret_str = NULL;
3530 	}
3531 	dhret = strdup("/tmp/x11vnc-dhret.XXXXXX");
3532 	omode = umask(077);
3533 	dhret_fd = mkstemp(dhret);
3534 	umask(omode);
3535 	if (dhret_fd < 0) {
3536 		free(dhret);
3537 		dhret = NULL;
3538 		dhret_fd = -1;
3539 	}
3540 
3541 	/* now fork the child to handle the SSL: */
3542 	pid = fork();
3543 
3544 	if (pid > 0) {
3545 		rfbLog("SSL: helper for peerport %d is pid %d: \n",
3546 		    peerport, (int) pid);
3547 	}
3548 
3549 	if (pid < 0) {
3550 		rfbLog("SSL: accept_openssl: could not fork.\n");
3551 		rfbLogPerror("fork");
3552 		close(sock);
3553 		close(csock);
3554 		if (mode == OPENSSL_INETD || ssl_no_fail) {
3555 			clean_up_exit(1);
3556 		}
3557 		return;
3558 
3559 	} else if (pid == 0) {
3560 		int s_in, s_out, httpsock = -1;
3561 		int vncsock;
3562 		int i, have_httpd = 0;
3563 		int f_in  = fileno(stdin);
3564 		int f_out = fileno(stdout);
3565 		int skip_vnc_tls = mode == OPENSSL_HTTPS ? 1 : 0;
3566 
3567 		if (db) fprintf(stderr, "helper pid in: %d %d %d %d\n", f_in, f_out, sock, listen);
3568 
3569 		/* reset all handlers to default (no interrupted() calls) */
3570 		unset_signals();
3571 
3572 		/* close all non-essential fd's */
3573 		for (i=0; i<256; i++) {
3574 			if (mode == OPENSSL_INETD) {
3575 				if (i == f_in || i == f_out) {
3576 					continue;
3577 				}
3578 			}
3579 			if (i == sock) {
3580 				continue;
3581 			}
3582 			if (i == 2) {
3583 				continue;
3584 			}
3585 			close(i);
3586 		}
3587 
3588 		/*
3589 		 * sadly, we are a long lived child and so the large
3590 		 * framebuffer memory areas will soon differ from parent.
3591 		 * try to free as much as possible.
3592 		 */
3593 		lose_ram();
3594 
3595 		/* now connect back to parent socket: */
3596 		vncsock = connect_tcp("127.0.0.1", cport);
3597 		if (vncsock < 0) {
3598 			rfbLog("SSL: ssl_helper[%d]: could not connect"
3599 			    " back to: %d\n", getpid(), cport);
3600 			rfbLog("SSL: ssl_helper[%d]: exit case 1 (no local vncsock)\n", getpid());
3601 			exit(1);
3602 		}
3603 		if (db) fprintf(stderr, "vncsock %d\n", vncsock);
3604 
3605 		/* try to initialize SSL with the remote client */
3606 
3607 		if (mode == OPENSSL_INETD) {
3608 			s_in  = fileno(stdin);
3609 			s_out = fileno(stdout);
3610 		} else {
3611 			s_in = s_out = sock;
3612 		}
3613 
3614 		if (! ssl_init(s_in, s_out, skip_vnc_tls, last_https)) {
3615 			close(vncsock);
3616 			rfbLog("SSL: ssl_helper[%d]: exit case 2 (ssl_init failed)\n", getpid());
3617 			exit(1);
3618 		}
3619 
3620 		if (vencrypt_selected != 0) {
3621 			char *tbuf;
3622 			tbuf = (char *) malloc(strlen(cookie) + 100);
3623 			sprintf(tbuf, "%s,VENCRYPT=%d,%s", uniq, vencrypt_selected, cookie);
3624 			write(vncsock, tbuf, strlen(cookie));
3625 			goto wrote_cookie;
3626 		} else if (anontls_selected != 0) {
3627 			char *tbuf;
3628 			tbuf = (char *) malloc(strlen(cookie) + 100);
3629 			sprintf(tbuf, "%s,ANONTLS=%d,%s", uniq, anontls_selected, cookie);
3630 			write(vncsock, tbuf, strlen(cookie));
3631 			goto wrote_cookie;
3632 		}
3633 
3634 		/*
3635 		 * things get messy below since we are trying to do
3636 		 * *both* VNC and Java applet httpd through the same
3637 		 * SSL socket.
3638 		 */
3639 
3640 		if (! screen) {
3641 			close(vncsock);
3642 			exit(1);
3643 		}
3644 		if (screen->httpListenSock >= 0 && screen->httpPort > 0) {
3645 			have_httpd = 1;
3646 		} else if (ipv6_http_fd >= 0) {
3647 			have_httpd = 1;
3648 		} else if (screen->httpListenSock == -2) {
3649 			have_httpd = 1;
3650 		}
3651 		if (mode == OPENSSL_HTTPS && ! have_httpd) {
3652 			rfbLog("SSL: accept_openssl[%d]: no httpd socket for "
3653 			    "-https mode\n", getpid());
3654 			close(vncsock);
3655 			rfbLog("SSL: ssl_helper[%d]: exit case 3 (no httpd sock)\n", getpid());
3656 			exit(1);
3657 		}
3658 
3659 		if (have_httpd) {
3660 			int n = 0, is_http = 0;
3661 			int hport = screen->httpPort;
3662 			char *iface = NULL;
3663 			char *buf, *tbuf;
3664 
3665 			buf  = (char *) calloc((ABSIZE+1), 1);
3666 			tbuf = (char *) calloc((2*ABSIZE+1), 1);
3667 
3668 			if (mode == OPENSSL_HTTPS) {
3669 				/*
3670 				 * for this mode we know it is HTTP traffic
3671 				 * so we skip trying to guess.
3672 				 */
3673 				is_http = 1;
3674 				n = 0;
3675 				goto connect_to_httpd;
3676 			}
3677 
3678 			/*
3679 			 * Check if there is stuff to read from remote end
3680 			 * if so it is likely a GET or HEAD.
3681 			 */
3682 			if (! is_ssl_readable(s_in, last_https, last_get,
3683 			    mode)) {
3684 				goto write_cookie;
3685 			}
3686 
3687 			/*
3688 			 * read first 2 bytes to try to guess.  sadly,
3689 			 * the user is often pondering a "non-verified
3690 			 * cert" dialog for a long time before the GET
3691 			 * is ever sent.  So often we timeout here.
3692 			 */
3693 
3694 			if (db) fprintf(stderr, "watch_for_http_traffic\n");
3695 
3696 			is_http = watch_for_http_traffic(buf, &n, s_in);
3697 
3698 			if (is_http < 0 || is_http == 0) {
3699 				/*
3700 				 * error or http not detected, fall back
3701 				 * to normal VNC socket.
3702 				 */
3703 				if (db) fprintf(stderr, "is_http err: %d n: %d\n", is_http, n);
3704 				write(vncsock, cookie, strlen(cookie));
3705 				if (n > 0) {
3706 					write(vncsock, buf, n);
3707 				}
3708 				goto wrote_cookie;
3709 			}
3710 
3711 			if (db) fprintf(stderr, "is_http: %d n: %d\n",
3712 			    is_http, n);
3713 			if (db) fprintf(stderr, "buf: '%s'\n", buf);
3714 
3715 			if (strstr(buf, "/request.https.vnc.connection")) {
3716 				char reply[] = "HTTP/1.0 200 OK\r\n"
3717 				    "Content-Type: octet-stream\r\n"
3718 				    "Connection: Keep-Alive\r\n"
3719 				    "VNC-Server: x11vnc\r\n"
3720 				    "Pragma: no-cache\r\n\r\n";
3721 				/*
3722 				 * special case proxy coming thru https
3723 				 * instead of a direct SSL connection.
3724 				 */
3725 				rfbLog("Handling VNC request via https GET. [%d]\n", getpid());
3726 				rfbLog("-- %s\n", buf);
3727 
3728 				if (strstr(buf, "/reverse.proxy")) {
3729 					char *buf2;
3730 					int n, ptr;
3731 #if !LIBVNCSERVER_HAVE_LIBSSL && !HAVE_LIBSSL
3732 					write(s_out, reply, strlen(reply));
3733 #else
3734 					SSL_write(ssl, reply, strlen(reply));
3735 #endif
3736 
3737 					buf2  = (char *) calloc((8192+1), 1);
3738 					n = 0;
3739 					ptr = 0;
3740 					while (ptr < 8192) {
3741 #if !LIBVNCSERVER_HAVE_LIBSSL && !HAVE_LIBSSL
3742 						n = read(s_in, buf2 + ptr, 1);
3743 #else
3744 						n = SSL_read(ssl, buf2 + ptr, 1);
3745 #endif
3746 						if (n > 0) {
3747 							ptr += n;
3748 						}
3749 						if (db) fprintf(stderr, "buf2: '%s'\n", buf2);
3750 
3751 						if (strstr(buf2, "\r\n\r\n")) {
3752 							break;
3753 						}
3754 					}
3755 					free(buf2);
3756 				}
3757 				goto write_cookie;
3758 
3759 			} else if (strstr(buf, "/check.https.proxy.connection")) {
3760 				char reply[] = "HTTP/1.0 200 OK\r\n"
3761 				    "Connection: close\r\n"
3762 				    "Content-Type: octet-stream\r\n"
3763 				    "VNC-Server: x11vnc\r\n"
3764 				    "Pragma: no-cache\r\n\r\n";
3765 
3766 				rfbLog("Handling Check HTTPS request via https GET. [%d]\n", getpid());
3767 				rfbLog("-- %s\n", buf);
3768 
3769 #if !LIBVNCSERVER_HAVE_LIBSSL && !HAVE_LIBSSL
3770 				write(s_out, reply, strlen(reply));
3771 #else
3772 				SSL_write(ssl, reply, strlen(reply));
3773 				SSL_shutdown(ssl);
3774 #endif
3775 
3776 				strcpy(tbuf, uniq);
3777 				strcat(tbuf, cookie);
3778 				write(vncsock, tbuf, strlen(tbuf));
3779 				close(vncsock);
3780 
3781 				rfbLog("SSL: ssl_helper[%d]: exit case 4 (check.https.proxy.connection)\n", getpid());
3782 				exit(0);
3783 			}
3784 			connect_to_httpd:
3785 
3786 			/*
3787 			 * Here we go... no turning back.  we have to
3788 			 * send failure to parent and close socket to have
3789 			 * http processed at all in a timely fashion...
3790 			 */
3791 
3792 			/* send the failure tag: */
3793 			strcpy(tbuf, uniq);
3794 
3795 			if (https_port_redir < 0 || (strstr(buf, "PORT=") || strstr(buf, "port="))) {
3796 				char *q = strstr(buf, "Host:");
3797 				int fport = 443, match = 0;
3798 				char num[16];
3799 
3800 				if (q && strstr(q, "\n")) {
3801 				    q += strlen("Host:") + 1;
3802 				    while (*q != '\n') {
3803 					int p;
3804 					if (*q == ':' && sscanf(q, ":%d", &p) == 1) {
3805 						if (p > 0 && p < 65536) {
3806 							fport = p;
3807 							match = 1;
3808 							break;
3809 						}
3810 					}
3811 					q++;
3812 				    }
3813 				}
3814 				if (!match || !https_port_redir) {
3815 					int p;
3816 					if (sscanf(buf, "PORT=%d,", &p) == 1) {
3817 						if (p > 0 && p < 65536) {
3818 							fport = p;
3819 						}
3820 					} else if (sscanf(buf, "port=%d,", &p) == 1) {
3821 						if (p > 0 && p < 65536) {
3822 							fport = p;
3823 						}
3824 					}
3825 				}
3826 				sprintf(num, "HP=%d,", fport);
3827 				strcat(tbuf, num);
3828 			}
3829 
3830 			if (strstr(buf, "HTTP/") != NULL)  {
3831 				char *q, *str;
3832 				/*
3833 				 * Also send back the GET line for heuristics.
3834 				 * (last_https, get file).
3835 				 */
3836 				str = strdup(buf);
3837 				q = strstr(str, "HTTP/");
3838 				if (q != NULL) {
3839 					*q = '\0';
3840 					strcat(tbuf, str);
3841 				}
3842 				free(str);
3843 			}
3844 
3845 			/*
3846 			 * Also send the cookie to pad out the number of
3847 			 * bytes to more than the parent wants to read.
3848 			 * Since this is the failure case, it does not
3849 			 * matter that we send more than strlen(cookie).
3850 			 */
3851 			strcat(tbuf, cookie);
3852 			write(vncsock, tbuf, strlen(tbuf));
3853 
3854 			usleep(150*1000);
3855 			if (db) fprintf(stderr, "close vncsock: %d\n", vncsock);
3856 			close(vncsock);
3857 
3858 			/* now, finally, connect to the libvncserver httpd: */
3859 			if (screen->listenInterface == htonl(INADDR_ANY) ||
3860 			    screen->listenInterface == htonl(INADDR_NONE)) {
3861 				iface = "127.0.0.1";
3862 			} else {
3863 				struct in_addr in;
3864 				in.s_addr = screen->listenInterface;
3865 				iface = inet_ntoa(in);
3866 			}
3867 			if (iface == NULL || !strcmp(iface, "")) {
3868 				iface = "127.0.0.1";
3869 			}
3870 			if (db) fprintf(stderr, "iface: %s:%d\n", iface, hport);
3871 			usleep(150*1000);
3872 
3873 			httpsock = connect_tcp(iface, hport);
3874 
3875 			if (httpsock < 0) {
3876 				/* UGH, after all of that! */
3877 				rfbLog("Could not connect to httpd socket!\n");
3878 				rfbLog("SSL: ssl_helper[%d]: exit case 5.\n", getpid());
3879 				exit(1);
3880 			}
3881 			if (db) fprintf(stderr, "ssl_helper[%d]: httpsock: %d %d\n",
3882 			    getpid(), httpsock, n);
3883 
3884 			/*
3885 			 * send what we read to httpd, and then connect
3886 			 * the rest of the SSL session to it:
3887 			 */
3888 			if (n > 0) {
3889 				char *s = getenv("X11VNC_EXTRA_HTTPS_PARAMS");
3890 				int did_extra = 0;
3891 
3892 				if (db) fprintf(stderr, "sending http buffer httpsock: %d n=%d\n'%s'\n", httpsock, n, buf);
3893 				if (s != NULL) {
3894 					char *q = strstr(buf, " HTTP/");
3895 					if (q) {
3896 						int m;
3897 						*q = '\0';
3898 						m = strlen(buf);
3899 						write(httpsock, buf, m);
3900 						write(httpsock, s, strlen(s));
3901 						*q = ' ';
3902 						write(httpsock, q, n-m);
3903 						did_extra = 1;
3904 					}
3905 				}
3906 				if (!did_extra) {
3907 					write(httpsock, buf, n);
3908 				}
3909 			}
3910 			ssl_xfer(httpsock, s_in, s_out, is_http);
3911 			rfbLog("SSL: ssl_helper[%d]: exit case 6 (https ssl_xfer done)\n", getpid());
3912 			exit(0);
3913 		}
3914 
3915 		/*
3916 		 * ok, back from the above https mess, simply send the
3917 		 * cookie back to the parent (who will attach us to
3918 		 * libvncserver), and connect the rest of the SSL session
3919 		 * to it.
3920 		 */
3921 		write_cookie:
3922 		write(vncsock, cookie, strlen(cookie));
3923 
3924 		wrote_cookie:
3925 		ssl_xfer(vncsock, s_in, s_out, 0);
3926 		rfbLog("SSL: ssl_helper[%d]: exit case 7 (ssl_xfer done)\n", getpid());
3927 		if (0) usleep(50 * 1000);
3928 		exit(0);
3929 	}
3930 	/* parent here */
3931 
3932 	if (mode != OPENSSL_INETD) {
3933 		close(sock);
3934 	}
3935 	if (db) fprintf(stderr, "helper process is: %d\n", pid);
3936 
3937 	/* accept connection from our child.  */
3938 	signal(SIGALRM, csock_timeout);
3939 	csock_timeout_sock = csock;
3940 	alarm(20);
3941 
3942 	vsock = accept(csock, (struct sockaddr *)&addr, &addrlen);
3943 
3944 	alarm(0);
3945 	signal(SIGALRM, SIG_DFL);
3946 	close(csock);
3947 
3948 
3949 	if (vsock < 0) {
3950 		rfbLog("SSL: accept_openssl: connection from ssl_helper[%d] FAILED.\n", pid);
3951 		rfbLogPerror("accept");
3952 
3953 		kill(pid, SIGTERM);
3954 		waitpid(pid, &status, WNOHANG);
3955 		if (mode == OPENSSL_INETD || ssl_no_fail) {
3956 			clean_up_exit(1);
3957 		}
3958 		if (certret_fd >= 0) {
3959 			close(certret_fd);
3960 			certret_fd = -1;
3961 		}
3962 		if (certret) {
3963 			unlink(certret);
3964 		}
3965 		if (dhret_fd >= 0) {
3966 			close(dhret_fd);
3967 			dhret_fd = -1;
3968 		}
3969 		if (dhret) {
3970 			unlink(dhret);
3971 		}
3972 		return;
3973 	}
3974 	if (db) fprintf(stderr, "accept_openssl: vsock: %d\n", vsock);
3975 
3976 	n = read(vsock, rcookie, strlen(cookie));
3977 	if (n < 0 && errno != 0) {
3978 		rfbLogPerror("read");
3979 	}
3980 
3981 	if (certret) {
3982 		struct stat sbuf;
3983 		sbuf.st_size = 0;
3984 		if (certret_fd >= 0 && stat(certret, &sbuf) == 0 && sbuf.st_size > 0) {
3985 			certret_str = (char *) calloc(sbuf.st_size+1, 1);
3986 			read(certret_fd, certret_str, sbuf.st_size);
3987 			close(certret_fd);
3988 			certret_fd = -1;
3989 		}
3990 		if (certret_fd >= 0) {
3991 			close(certret_fd);
3992 			certret_fd = -1;
3993 		}
3994 		unlink(certret);
3995 		if (certret_str && strstr(certret_str, "NOCERT") == certret_str) {
3996 			free(certret_str);
3997 			certret_str = NULL;
3998 		}
3999 		if (0 && certret_str) {
4000 			fprintf(stderr, "certret_str[%d]:\n%s\n", (int) sbuf.st_size, certret_str);
4001 		}
4002 	}
4003 
4004 	if (dhret) {
4005 		struct stat sbuf;
4006 		sbuf.st_size = 0;
4007 		if (dhret_fd >= 0 && stat(dhret, &sbuf) == 0 && sbuf.st_size > 0) {
4008 			dhret_str = (char *) calloc(sbuf.st_size+1, 1);
4009 			read(dhret_fd, dhret_str, sbuf.st_size);
4010 			close(dhret_fd);
4011 			dhret_fd = -1;
4012 		}
4013 		if (dhret_fd >= 0) {
4014 			close(dhret_fd);
4015 			dhret_fd = -1;
4016 		}
4017 		unlink(dhret);
4018 		if (dhret_str && strstr(dhret_str, "NOCERT") == dhret_str) {
4019 			free(dhret_str);
4020 			dhret_str = NULL;
4021 		}
4022 		if (dhret_str) {
4023 			if (new_dh_params == NULL) {
4024 				fprintf(stderr, "dhret_str[%d]:\n%s\n", (int) sbuf.st_size, dhret_str);
4025 				new_dh_params = strdup(dhret_str);
4026 			}
4027 		}
4028 	}
4029 
4030 	if (0) {
4031 		fprintf(stderr, "rcookie: %s\n", rcookie);
4032 		fprintf(stderr, "cookie:  %s\n", cookie);
4033 	}
4034 
4035 	if (strstr(rcookie, uniq) == rcookie) {
4036 		char *q = strstr(rcookie, "RB=");
4037 		if (q && strstr(cookie, q) == cookie) {
4038 			vencrypt_sel = 0;
4039 			anontls_sel = 0;
4040 			q = strstr(rcookie, "VENCRYPT=");
4041 			if (q && sscanf(q, "VENCRYPT=%d,", &vencrypt_sel) == 1) {
4042 				if (vencrypt_sel != 0) {
4043 					rfbLog("SSL: VENCRYPT mode=%d accepted. helper[%d]\n", vencrypt_sel, pid);
4044 					goto accept_client;
4045 				}
4046 			}
4047 			q = strstr(rcookie, "ANONTLS=");
4048 			if (q && sscanf(q, "ANONTLS=%d,", &anontls_sel) == 1) {
4049 				if (anontls_sel != 0) {
4050 					rfbLog("SSL: ANONTLS mode=%d accepted. helper[%d]\n", anontls_sel, pid);
4051 					goto accept_client;
4052 				}
4053 			}
4054 		}
4055 	}
4056 
4057 	if (n != (int) strlen(cookie) || strncmp(cookie, rcookie, n)) {
4058 		rfbLog("SSL: accept_openssl: cookie from ssl_helper[%d] FAILED. %d\n", pid, n);
4059 		if (db) fprintf(stderr, "'%s'\n'%s'\n", cookie, rcookie);
4060 		close(vsock);
4061 
4062 		if (strstr(rcookie, uniq) == rcookie) {
4063 			int i;
4064 			double https_download_wait_time = 15.0;
4065 
4066 			if (getenv("X11VNC_HTTPS_DOWNLOAD_WAIT_TIME")) {
4067 				https_download_wait_time = atof(getenv("X11VNC_HTTPS_DOWNLOAD_WAIT_TIME"));
4068 			}
4069 
4070 			rfbLog("SSL: BUT WAIT! HTTPS for helper process[%d] succeeded. Good.\n", pid);
4071 			if (mode != OPENSSL_HTTPS) {
4072 				last_https = dnow();
4073 				for (i=0; i<256; i++) {
4074 					last_get[i] = '\0';
4075 				}
4076 				strncpy(last_get, rcookie, 100);
4077 				if (db) fprintf(stderr, "last_get: '%s'\n", last_get);
4078 			}
4079 			if (rcookie && strstr(rcookie, "VncViewer.class")) {
4080 				rfbLog("\n");
4081 				rfbLog("helper[%d]:\n", pid);
4082 				rfbLog("***********************************************************\n");
4083 				rfbLog("SSL: WARNING CLIENT ASKED FOR NONEXISTENT 'VncViewer.class'\n");
4084 				rfbLog("SSL: USER NEEDS TO MAKE SURE THE JAVA PLUGIN IS INSTALLED\n");
4085 				rfbLog("SSL: AND WORKING PROPERLY (e.g. a test-java-plugin page.)\n");
4086 				rfbLog("SSL: AND/OR USER NEEDS TO **RESTART** HIS WEB BROWSER.\n");
4087 				rfbLog("SSL: SOMETIMES THE BROWSER 'REMEMBERS' FAILED APPLET DOWN-\n");
4088 				rfbLog("SSL: LOADS AND RESTARTING IT IS THE ONLY WAY TO FIX THINGS.\n");
4089 				rfbLog("***********************************************************\n");
4090 				rfbLog("\n");
4091 			}
4092 			ssl_helper_pid(pid, -2);
4093 
4094 			if (https_port_redir) {
4095 				double start;
4096 				int origport = screen->port;
4097 				int useport = screen->port;
4098 				int saw_httpsock = 0;
4099 				/* to expand $PORT correctly in index.vnc */
4100 				if (https_port_redir < 0) {
4101 					char *q = strstr(rcookie, "HP=");
4102 					if (q) {
4103 						int p;
4104 						if (sscanf(q, "HP=%d,", &p) == 1) {
4105 							useport = p;
4106 						}
4107 					}
4108 				} else {
4109 					useport = https_port_redir;
4110 				}
4111 				screen->port = useport;
4112 				if (origport != useport) {
4113 					rfbLog("SSL: -httpsredir guess port: %d  helper[%d]\n", screen->port, pid);
4114 				}
4115 
4116 				start = dnow();
4117 				while (dnow() < start + https_download_wait_time) {
4118 					if (screen->httpSock >= 0) saw_httpsock = 1;
4119 					rfbPE(10000);
4120 					usleep(10000);
4121 					if (screen->httpSock >= 0) saw_httpsock = 1;
4122 					waitpid(pid, &status, WNOHANG);
4123 					if (kill(pid, 0) != 0) {
4124 						rfbLog("SSL: helper[%d] pid finished\n", pid);
4125 						break;
4126 					}
4127 					if (0 && saw_httpsock && screen->httpSock < 0) {
4128 						/* this check can kill the helper too soon. */
4129 						rfbLog("SSL: httpSock for helper[%d] went away\n", pid);
4130 						break;
4131 					}
4132 				}
4133 				rfbLog("SSL: guessing child helper[%d] https finished. dt=%.6f\n",
4134 				    pid, dnow() - start);
4135 
4136 				rfbPE(10000);
4137 				rfbPE(10000);
4138 				rfbPE(10000);
4139 
4140 				screen->port = origport;
4141 				ssl_helper_pid(0, -2);
4142 				if (mode == OPENSSL_INETD) {
4143 					clean_up_exit(1);
4144 				}
4145 			} else if (mode == OPENSSL_INETD) {
4146 				double start;
4147 				int saw_httpsock = 0;
4148 
4149 				/* to expand $PORT correctly in index.vnc */
4150 				if (screen->port == 0) {
4151 					int fd = fileno(stdin);
4152 					if (getenv("X11VNC_INETD_PORT")) {
4153 						/* mutex */
4154 						screen->port = atoi(getenv(
4155 						    "X11VNC_INETD_PORT"));
4156 					} else {
4157 						int tport = get_local_port(fd);
4158 						if (tport > 0) {
4159 							screen->port = tport;
4160 						}
4161 					}
4162 				}
4163 				rfbLog("SSL: screen->port %d for helper[%d]\n", screen->port, pid);
4164 
4165 				/* kludge for https fetch via inetd */
4166 				start = dnow();
4167 				while (dnow() < start + https_download_wait_time) {
4168 					if (screen->httpSock >= 0) saw_httpsock = 1;
4169 					rfbPE(10000);
4170 					usleep(10000);
4171 					if (screen->httpSock >= 0) saw_httpsock = 1;
4172 					waitpid(pid, &status, WNOHANG);
4173 					if (kill(pid, 0) != 0) {
4174 						rfbLog("SSL: helper[%d] pid finished\n", pid);
4175 						break;
4176 					}
4177 					if (0 && saw_httpsock && screen->httpSock < 0) {
4178 						/* this check can kill the helper too soon. */
4179 						rfbLog("SSL: httpSock for helper[%d] went away\n", pid);
4180 						break;
4181 					}
4182 				}
4183 				rfbLog("SSL: OPENSSL_INETD guessing "
4184 				    "child helper[%d] https finished. dt=%.6f\n",
4185 				    pid, dnow() - start);
4186 
4187 				rfbPE(10000);
4188 				rfbPE(10000);
4189 				rfbPE(10000);
4190 
4191 				ssl_helper_pid(0, -2);
4192 				clean_up_exit(1);
4193 			}
4194 			/* this will actually only get earlier https */
4195 			ssl_helper_pid(0, -2);
4196 			return;
4197 		}
4198 		kill(pid, SIGTERM);
4199 		waitpid(pid, &status, WNOHANG);
4200 		if (mode == OPENSSL_INETD || ssl_no_fail) {
4201 			clean_up_exit(1);
4202 		}
4203 		return;
4204 	}
4205 
4206 	accept_client:
4207 
4208 	if (db) fprintf(stderr, "accept_openssl: cookie good: %s\n", cookie);
4209 
4210 	rfbLog("SSL: handshake with helper process[%d] succeeded.\n", pid);
4211 
4212 	openssl_last_helper_pid = pid;
4213 	ssl_helper_pid(pid, vsock);
4214 
4215 	if (vnc_redirect) {
4216 		vnc_redirect_sock = vsock;
4217 		openssl_last_helper_pid = 0;
4218 		return;
4219 	}
4220 
4221 	client = create_new_client(vsock, 0);
4222 	openssl_last_helper_pid = 0;
4223 
4224 	if (client) {
4225 		int swt = 0;
4226 		if (mode == OPENSSL_VNC6 && openssl_last_ip != NULL) {
4227 			swt = 1;
4228 		} else if (mode == OPENSSL_REVERSE && ipv6_name != NULL && openssl_last_ip != NULL) {
4229 			swt = 1;
4230 		}
4231 		if (swt) {
4232 			if (client->host) {
4233 				free(client->host);
4234 			}
4235 			client->host = strdup(openssl_last_ip);
4236 		}
4237 		if (db) fprintf(stderr, "accept_openssl: client %p\n", (void *) client);
4238 		if (db) fprintf(stderr, "accept_openssl: new_client %p\n", (void *) screen->newClientHook);
4239 		if (db) fprintf(stderr, "accept_openssl: new_client %p\n", (void *) new_client);
4240 		if (mode == OPENSSL_INETD) {
4241 			inetd_client = client;
4242 			client->clientGoneHook = client_gone;
4243 		}
4244 		if (openssl_last_ip &&
4245 		    strpbrk(openssl_last_ip, "0123456789") == openssl_last_ip) {
4246 			client->host = strdup(openssl_last_ip);
4247 		}
4248 		if (vencrypt_sel != 0) {
4249 			client->protocolMajorVersion = 3;
4250 			client->protocolMinorVersion = 8;
4251 #if LIBVNCSERVER_HAVE_LIBSSL || HAVE_LIBSSL
4252 			if (!finish_vencrypt_auth(client, vencrypt_sel)) {
4253 				rfbCloseClient(client);
4254 				client = NULL;
4255 			}
4256 #else
4257 			badnews("3 accept_openssl");
4258 #endif
4259 		} else if (anontls_sel != 0) {
4260 			client->protocolMajorVersion = 3;
4261 			client->protocolMinorVersion = 8;
4262 			rfbAuthNewClient(client);
4263 		}
4264 		if (use_threads && client != NULL) {
4265 			rfbStartOnHoldClient(client);
4266 		}
4267 		/* try to get RFB proto done now. */
4268 		progress_client();
4269 	} else {
4270 		rfbLog("SSL: accept_openssl: rfbNewClient failed.\n");
4271 		close(vsock);
4272 
4273 		kill(pid, SIGTERM);
4274 		waitpid(pid, &status, WNOHANG);
4275 		if (mode == OPENSSL_INETD || ssl_no_fail) {
4276 			clean_up_exit(1);
4277 		}
4278 		return;
4279 	}
4280 }
4281 
raw_xfer(int csock,int s_in,int s_out)4282 void raw_xfer(int csock, int s_in, int s_out) {
4283 	char buf0[8192];
4284 	int sz = 8192, n, m, status, db = 1;
4285 	char *buf;
4286 #ifdef FORK_OK
4287 	pid_t par = getpid();
4288 	pid_t pid = fork();
4289 
4290 	buf = buf0;
4291 	if (vnc_redirect) {
4292 		/* change buf size some direction. */
4293 	}
4294 
4295 	if (getenv("X11VNC_DEBUG_RAW_XFER")) {
4296 		db = atoi(getenv("X11VNC_DEBUG_RAW_XFER"));
4297 	}
4298 	if (pid < 0) {
4299 		exit(1);
4300 	}
4301 	/* this is for testing or special helper usage, no SSL just socket redir */
4302 	if (pid) {
4303 		if (db) rfbLog("raw_xfer start: %d -> %d/%d\n", csock, s_in, s_out);
4304 
4305 		while (1) {
4306 			n = read(csock, buf, sz);
4307 			if (n == 0 || (n < 0 && errno != EINTR) ) {
4308 				break;
4309 			} else if (n > 0) {
4310 				int len = n;
4311 				char *src = buf;
4312 				if (db > 1) write(2, buf, n);
4313 				while (len > 0) {
4314 					m = write(s_out, src, len);
4315 					if (m > 0) {
4316 						src += m;
4317 						len -= m;
4318 						continue;
4319 					}
4320 					if (m < 0 && (errno == EINTR || errno == EAGAIN)) {
4321 						continue;
4322 					}
4323 if (db) rfbLog("raw_xfer bad write:  %d -> %d | %d/%d  errno=%d\n", csock, s_out, m, n, errno);
4324 					break;
4325 				}
4326 			}
4327 		}
4328 		usleep(250*1000);
4329 		kill(pid, SIGTERM);
4330 		waitpid(pid, &status, WNOHANG);
4331 		if (db) rfbLog("raw_xfer done:  %d -> %d\n", csock, s_out);
4332 
4333 	} else {
4334 		if (db) usleep(50*1000);
4335 		if (db) rfbLog("raw_xfer start: %d <- %d\n", csock, s_in);
4336 
4337 		while (1) {
4338 			n = read(s_in, buf, sz);
4339 			if (n == 0 || (n < 0 && errno != EINTR) ) {
4340 				break;
4341 			} else if (n > 0) {
4342 				int len = n;
4343 				char *src = buf;
4344 				if (db > 1) write(2, buf, n);
4345 				while (len > 0) {
4346 					m = write(csock, src, len);
4347 					if (m > 0) {
4348 						src += m;
4349 						len -= m;
4350 						continue;
4351 					}
4352 					if (m < 0 && (errno == EINTR || errno == EAGAIN)) {
4353 						continue;
4354 					}
4355 		if (db) rfbLog("raw_xfer bad write:  %d <- %d | %d/%d errno=%d\n", csock, s_in, m, n, errno);
4356 					break;
4357 				}
4358 			}
4359 		}
4360 		usleep(250*1000);
4361 		kill(par, SIGTERM);
4362 		waitpid(par, &status, WNOHANG);
4363 		if (db) rfbLog("raw_xfer done:  %d <- %d\n", csock, s_in);
4364 	}
4365 	close(csock);
4366 	close(s_in);
4367 	close(s_out);
4368 #endif	/* FORK_OK */
4369 }
4370 
4371 /* compile with -DENC_HAVE_OPENSSL=0 to disable enc stuff but still have ssl */
4372 
4373 #define ENC_MODULE
4374 
4375 #if LIBVNCSERVER_HAVE_LIBSSL || HAVE_LIBSSL
4376 #ifndef ENC_HAVE_OPENSSL
4377 #define ENC_HAVE_OPENSSL 1
4378 #endif
4379 #else
4380 #define ENC_HAVE_OPENSSL 0
4381 #endif
4382 
4383 #define ENC_DISABLE_SHOW_CERT
4384 
4385 #include "enc.h"
4386 
symmetric_encryption_xfer(int csock,int s_in,int s_out)4387 static void symmetric_encryption_xfer(int csock, int s_in, int s_out) {
4388 	char tmp[100];
4389 	char *cipher, *keyfile, *q;
4390 
4391 	if (! enc_str) {
4392 		return;
4393 	}
4394 	cipher = (char *) malloc(strlen(enc_str) + 100);
4395 	q = strchr(enc_str, ':');
4396 	if (!q) return;
4397 	*q = '\0';
4398 	if (getenv("X11VNC_USE_ULTRADSM_IV")) {
4399 		sprintf(cipher, "rev:%s", enc_str);
4400 	} else {
4401 		sprintf(cipher, "noultra:rev:%s", enc_str);
4402 	}
4403 	keyfile = strdup(q+1);
4404 	*q = ':';
4405 
4406 
4407 	/* TBD: s_in != s_out */
4408 	if (s_out) {}
4409 
4410 	sprintf(tmp, "fd=%d,%d", s_in, csock);
4411 
4412 	enc_do(cipher, keyfile, "-1", tmp);
4413 }
4414 
4415