/* * Normal exiting */ void clean_up_exit (int ret) { static int depth = 0; exit_flag = 1; if (depth++ > 2) { exit(ret); } if (icon_mode) { clean_icon_mode(); } /* remove the shm areas: */ clean_shm(0); stop_stunnel(); if (use_openssl) { ssl_helper_pid(0, 0); /* killall */ } if (! dpy) exit(ret); /* raw_rb hack */ /* X keyboard cleanups */ delete_added_keycodes(0); if (clear_mods == 1) { clear_modifiers(0); } else if (clear_mods == 2) { clear_keys(); } if (no_autorepeat) { autorepeat(1, 0); } if (use_solid_bg) { solid_bg(1); } X_LOCK; XTestDiscard_wr(dpy); #if LIBVNCSERVER_HAVE_LIBXDAMAGE if (xdamage) { XDamageDestroy(dpy, xdamage); } #endif #if LIBVNCSERVER_HAVE_LIBXTRAP if (trap_ctx) { XEFreeTC(trap_ctx); } #endif /* XXX rdpy_ctrl, etc. cannot close w/o blocking */ XCloseDisplay_wr(dpy); X_UNLOCK; fflush(stderr); exit(ret); }
/* * General problem handler */ static void interrupted (int sig) { exit_sig = sig; if (exit_flag) { fprintf(stderr, "extra[%d] signal: %d\n", exit_flag, sig); exit_flag++; if (use_threads) { usleep2(250 * 1000); } else if (exit_flag <= 2) { return; } if (rm_flagfile) { unlink(rm_flagfile); rm_flagfile = NULL; } exit(4); } exit_flag++; if (sig == 0) { fprintf(stderr, "caught X11 error:\n"); if (crash_debug) { crash_shell(); } } else if (sig == -1) { fprintf(stderr, "caught XIO error:\n"); } else { fprintf(stderr, "caught signal: %d\n", sig); } if (sig == SIGINT) { shut_down = 1; return; } if (crash_debug) { crash_shell(); } X_UNLOCK; if (icon_mode) { clean_icon_mode(); } /* remove the shm areas with quick=1: */ clean_shm(1); if (sig == -1) { /* not worth trying any more cleanup, X server probably gone */ if (rm_flagfile) { unlink(rm_flagfile); rm_flagfile = NULL; } exit(3); } /* X keyboard cleanups */ delete_added_keycodes(0); if (clear_mods == 1) { clear_modifiers(0); } else if (clear_mods == 2) { clear_keys(); } else if (clear_mods == 3) { clear_keys(); clear_locks(); } if (no_autorepeat) { autorepeat(1, 0); } if (use_solid_bg) { solid_bg(1); } if (ncache || ncache0) { kde_no_animate(1); } stop_stunnel(); if (crash_debug) { crash_shell(); } if (sig) { if (rm_flagfile) { unlink(rm_flagfile); rm_flagfile = NULL; } exit(2); } }
/* * Normal exiting */ void clean_up_exit(int ret) { static int depth = 0; exit_flag = 1; if (depth++ > 2) { exit(ret); } if (icon_mode) { clean_icon_mode(); } /* remove the shm areas: */ clean_shm(0); stop_stunnel(); if (use_openssl) { ssl_helper_pid(0, 0); /* killall */ } if (ssh_pid > 0) { kill(ssh_pid, SIGTERM); ssh_pid = 0; } #ifdef MACOSX if (client_connect_file) { if (strstr(client_connect_file, "/tmp/x11vnc-macosx-remote") == client_connect_file) { unlink(client_connect_file); } } if (macosx_console) { macosxCG_fini(); } #endif if (pipeinput_fh != NULL) { pclose(pipeinput_fh); pipeinput_fh = NULL; } shutdown_uinput(); if (unix_sock) { if (unix_sock_fd >= 0) { rfbLog("deleting unix sock: %s\n", unix_sock); close(unix_sock_fd); unix_sock_fd = -1; unlink(unix_sock); } } if (! dpy) { /* raw_rb hack */ if (rm_flagfile) { unlink(rm_flagfile); rm_flagfile = NULL; } exit(ret); } /* X keyboard cleanups */ delete_added_keycodes(0); if (clear_mods == 1) { clear_modifiers(0); } else if (clear_mods == 2) { clear_keys(); } else if (clear_mods == 3) { clear_keys(); clear_locks(); } if (no_autorepeat) { autorepeat(1, 0); } if (use_solid_bg) { solid_bg(1); } if (ncache || ncache0) { kde_no_animate(1); } X_LOCK; XTestDiscard_wr(dpy); #if LIBVNCSERVER_HAVE_LIBXDAMAGE if (xdamage) { XDamageDestroy(dpy, xdamage); } #endif #if LIBVNCSERVER_HAVE_LIBXTRAP if (trap_ctx) { XEFreeTC(trap_ctx); } #endif /* XXX rdpy_ctrl, etc. cannot close w/o blocking */ XCloseDisplay_wr(dpy); X_UNLOCK; fflush(stderr); if (rm_flagfile) { unlink(rm_flagfile); rm_flagfile = NULL; } if (avahi) { avahi_cleanup(); fflush(stderr); } exit(ret); }
int start_stunnel(int stunnel_port, int x11vnc_port, int hport, int x11vnc_hport) { #ifdef SSLCMDS char extra[] = ":/usr/sbin:/usr/local/sbin:/dist/sbin"; char *path, *p, *exe; char *stunnel_path = NULL; struct stat verify_buf; struct stat crl_buf; int status, tmp_pem = 0; if (stunnel_pid) { stop_stunnel(); } stunnel_pid = 0; path = getenv("PATH"); if (! path) { path = strdup(extra+1); } else { char *pt = path; path = (char *) malloc(strlen(path)+strlen(extra)+1); if (! path) { return 0; } strcpy(path, pt); strcat(path, extra); } exe = (char *) malloc(strlen(path) + 1 + strlen("stunnel4") + 1); p = strtok(path, ":"); exe[0] = '\0'; while (p) { struct stat sbuf; sprintf(exe, "%s/%s", p, "stunnel4"); if (! stunnel_path && stat(exe, &sbuf) == 0) { if (! S_ISDIR(sbuf.st_mode)) { stunnel_path = exe; break; } } sprintf(exe, "%s/%s", p, "stunnel"); if (! stunnel_path && stat(exe, &sbuf) == 0) { if (! S_ISDIR(sbuf.st_mode)) { stunnel_path = exe; break; } } p = strtok(NULL, ":"); } if (path) { free(path); } if (getenv("STUNNEL_PROG")) { free(exe); exe = strdup(getenv("STUNNEL_PROG")); stunnel_path = exe; } if (! stunnel_path) { free(exe); return 0; } if (stunnel_path[0] == '\0') { free(exe); return 0; } /* stunnel */ if (no_external_cmds || !cmd_ok("stunnel")) { rfbLogEnable(1); rfbLog("start_stunnel: cannot run external commands in -nocmds mode:\n"); rfbLog(" \"%s\"\n", stunnel_path); rfbLog(" exiting.\n"); clean_up_exit(1); } if (! quiet) { rfbLog("\n"); rfbLog("starting ssl tunnel: %s %d -> %d\n", stunnel_path, stunnel_port, x11vnc_port); } if (stunnel_pem && strstr(stunnel_pem, "SAVE") == stunnel_pem) { stunnel_pem = get_saved_pem(stunnel_pem, 1); if (! stunnel_pem) { rfbLog("start_stunnel: could not create or open" " saved PEM.\n"); clean_up_exit(1); } } else if (!stunnel_pem) { stunnel_pem = create_tmp_pem(NULL, 0); if (! stunnel_pem) { rfbLog("start_stunnel: could not create temporary," " self-signed PEM.\n"); clean_up_exit(1); } tmp_pem = 1; if (getenv("X11VNC_SHOW_TMP_PEM")) { FILE *in = fopen(stunnel_pem, "r"); if (in != NULL) { char line[128]; fprintf(stderr, "\n"); while (fgets(line, 128, in) != NULL) { fprintf(stderr, "%s", line); } fprintf(stderr, "\n"); fclose(in); } } } if (ssl_verify) { char *file = get_ssl_verify_file(ssl_verify); if (file) { ssl_verify = file; } if (stat(ssl_verify, &verify_buf) != 0) { rfbLog("stunnel: %s does not exist.\n", ssl_verify); clean_up_exit(1); } } if (ssl_crl) { if (stat(ssl_crl, &crl_buf) != 0) { rfbLog("stunnel: %s does not exist.\n", ssl_crl); clean_up_exit(1); } } stunnel_pid = fork(); if (stunnel_pid < 0) { stunnel_pid = 0; free(exe); return 0; } if (stunnel_pid == 0) { FILE *in; char fd[20]; int i; char *st_if = getenv("STUNNEL_LISTEN"); if (st_if == NULL) { st_if = ""; } else { st_if = (char *) malloc(strlen(st_if) + 2); sprintf(st_if, "%s:", getenv("STUNNEL_LISTEN")); } for (i=3; i<256; i++) { close(i); } if (use_stunnel == 3) { char sp[30], xp[30], *a = NULL; char *st = stunnel_path; char *pm = stunnel_pem; char *sv = ssl_verify; sprintf(sp, "%d", stunnel_port); sprintf(xp, "%d", x11vnc_port); if (ssl_verify) { if(S_ISDIR(verify_buf.st_mode)) { a = "-a"; } else { a = "-A"; } } if (ssl_crl) { rfbLog("stunnel: stunnel3 does not support CRL. %s\n", ssl_crl); clean_up_exit(1); } if (stunnel_pem && ssl_verify) { /* XXX double check -v 2 */ execlp(st, st, "-f", "-d", sp, "-r", xp, "-P", "none", "-p", pm, a, sv, "-v", "2", (char *) NULL); } else if (stunnel_pem && !ssl_verify) { execlp(st, st, "-f", "-d", sp, "-r", xp, "-P", "none", "-p", pm, (char *) NULL); } else if (!stunnel_pem && ssl_verify) { execlp(st, st, "-f", "-d", sp, "-r", xp, "-P", "none", a, sv, "-v", "2", (char *) NULL); } else { execlp(st, st, "-f", "-d", sp, "-r", xp, "-P", "none", (char *) NULL); } exit(1); } in = tmpfile(); if (! in) { exit(1); } fprintf(in, "foreground = yes\n"); fprintf(in, "pid =\n"); if (stunnel_pem) { fprintf(in, "cert = %s\n", stunnel_pem); } if (ssl_crl) { if(S_ISDIR(crl_buf.st_mode)) { fprintf(in, "CRLpath = %s\n", ssl_crl); } else { fprintf(in, "CRLfile = %s\n", ssl_crl); } } if (ssl_verify) { if(S_ISDIR(verify_buf.st_mode)) { fprintf(in, "CApath = %s\n", ssl_verify); } else { fprintf(in, "CAfile = %s\n", ssl_verify); } fprintf(in, "verify = 2\n"); } fprintf(in, ";debug = 7\n\n"); fprintf(in, "[x11vnc_stunnel]\n"); fprintf(in, "accept = %s%d\n", st_if, stunnel_port); fprintf(in, "connect = %d\n", x11vnc_port); if (hport > 0 && x11vnc_hport > 0) { fprintf(in, "\n[x11vnc_http]\n"); fprintf(in, "accept = %s%d\n", st_if, hport); fprintf(in, "connect = %d\n", x11vnc_hport); } fflush(in); rewind(in); if (getenv("STUNNEL_DEBUG")) { char line[1000]; fprintf(stderr, "\nstunnel config contents:\n\n"); while (fgets(line, sizeof(line), in) != NULL) { fprintf(stderr, "%s", line); } fprintf(stderr, "\n"); rewind(in); } sprintf(fd, "%d", fileno(in)); execlp(stunnel_path, stunnel_path, "-fd", fd, (char *) NULL); exit(1); } free(exe); usleep(750 * 1000); waitpid(stunnel_pid, &status, WNOHANG); if (ssl_verify && strstr(ssl_verify, "/sslverify-tmp-load-")) { /* temporary file */ usleep(1000 * 1000); unlink(ssl_verify); } if (tmp_pem) { /* temporary cert */ usleep(1500 * 1000); unlink(stunnel_pem); } if (kill(stunnel_pid, 0) != 0) { waitpid(stunnel_pid, &status, WNOHANG); stunnel_pid = 0; return 0; } if (! quiet) { rfbLog("stunnel pid is: %d\n", (int) stunnel_pid); } return 1; #else return 0; #endif }