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