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