1 /* 2 Copyright (C) 2002-2010 Karl J. Runge <runge (at) 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 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 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 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 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 (at) 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 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 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 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 696 int openssl_present(void) {return 0;} 697 void openssl_init(int isclient) {badnews("openssl_init");} 698 699 #define SSL_ERROR_NONE 0 700 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 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 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 } 750 int openssl_present(void) {return 0;} 751 752 #else 753 754 int openssl_present(void) {return 1;} 755 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 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 */ 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 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 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 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 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 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 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 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 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 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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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