Esempio n. 1
0
static int handle_subwin_resize(char *msg) {
	int new_x, new_y;
	int i, check = 10, ms = 250;	/* 2.5 secs total... */

	if (msg) {}	/* unused vars warning: */
	if (! subwin) {
		return 0;	/* hmmm... */
	}
	if (! valid_window(subwin, NULL, 0)) {
		rfbLogEnable(1);
		rfbLog("subwin 0x%lx went away!\n", subwin);
		X_UNLOCK;
		clean_up_exit(1);
	}
	if (! get_window_size(subwin, &new_x, &new_y)) {
		rfbLogEnable(1);
		rfbLog("could not get size of subwin 0x%lx\n", subwin);
		X_UNLOCK;
		clean_up_exit(1);
	}
	if (wdpy_x == new_x && wdpy_y == new_y) {
		/* no change */
		return 0;
	}

	/* window may still be changing (e.g. drag resize) */
	for (i=0; i < check; i++) {
		int newer_x, newer_y;
		usleep(ms * 1000);

		if (! get_window_size(subwin, &newer_x, &newer_y)) {
			rfbLogEnable(1);
			rfbLog("could not get size of subwin 0x%lx\n", subwin);
			clean_up_exit(1);
		}
		if (new_x == newer_x && new_y == newer_y) {
			/* go for it... */
			break;
		} else {
			rfbLog("subwin 0x%lx still changing size...\n", subwin);
			new_x = newer_x;
			new_y = newer_y;
		}
	}

	rfbLog("subwin 0x%lx new size: x: %d -> %d, y: %d -> %d\n",
	    subwin, wdpy_x, new_x, wdpy_y, new_y);
	rfbLog("calling handle_xrandr_change() for resizing\n");

	X_UNLOCK;
	handle_xrandr_change(new_x, new_y);
	return 1;
}
Esempio n. 2
0
void check_stunnel(void) {
	static time_t last_check = 0;
	time_t now = time(NULL);

	if (last_check + 3 >= now) {
		return;
	}
	last_check = now;

	/* double check that stunnel is still running: */

	if (stunnel_pid > 0) {
		int status;
#ifdef SSLCMDS
		waitpid(stunnel_pid, &status, WNOHANG); 
#endif
		if (kill(stunnel_pid, 0) != 0) {
#ifdef SSLCMDS
			waitpid(stunnel_pid, &status, WNOHANG); 
#endif
			rfbLog("stunnel subprocess %d died.\n", stunnel_pid); 
			stunnel_pid = 0;
			clean_up_exit(1);
		}
	}
}
Esempio n. 3
0
static void _avahi_entry_group_callback(AvahiEntryGroup *g,
    AvahiEntryGroupState state, void *userdata) {
	char *new_name;
	avahi_service_t *svc = (avahi_service_t *)userdata;

if (db) fprintf(stderr, "in  _avahi_entry_group_callback %d 0x%p\n", state, svc);
	if (g != _group && _group != NULL) {
		rfbLog("avahi_entry_group_callback fatal error (group).\n");
		clean_up_exit(1);
	}
	if (userdata == NULL) {
		rfbLog("avahi_entry_group_callback fatal error (userdata).\n");
		clean_up_exit(1);
	}

	switch(state) {
	case AVAHI_ENTRY_GROUP_ESTABLISHED:
		rfbLog("Avahi group %s established.\n", svc->name);
#if 0		/* is this the segv problem? */
		free(svc);
#endif
		break;
	case AVAHI_ENTRY_GROUP_COLLISION:
		new_name = avahi_alternative_service_name(svc->name);
		_avahi_create_services(new_name, svc->host, svc->port);
		rfbLog("Avahi Entry group collision\n");
		avahi_free(new_name);
		break;
	case AVAHI_ENTRY_GROUP_FAILURE:
		rfbLog("Avahi Entry group failure: %s\n",
		    avahi_strerror(avahi_client_errno(
		    avahi_entry_group_get_client(g))));
		break;
	default:
		break;
	}
if (db) fprintf(stderr, "out _avahi_entry_group_callback\n");
}
Esempio n. 4
0
static void handle_xrandr_change(int new_x, int new_y) {
	rfbClientIteratorPtr iter;
	rfbClientPtr cl;

	RAWFB_RET_VOID

	/* assumes no X_LOCK */

	/* sanity check xrandr_mode */
	if (! xrandr_mode) {
		xrandr_mode = strdup("default");
	} else if (! known_xrandr_mode(xrandr_mode)) {
		free(xrandr_mode);
		xrandr_mode = strdup("default");
	}
	rfbLog("xrandr_mode: %s\n", xrandr_mode);
	if (!strcmp(xrandr_mode, "exit")) {
		close_all_clients();
		rfbLog("  shutting down due to XRANDR event.\n");
		clean_up_exit(0);
	}
	if (!strcmp(xrandr_mode, "newfbsize") && screen) {
		iter = rfbGetClientIterator(screen);
		while( (cl = rfbClientIteratorNext(iter)) ) {
			if (cl->useNewFBSize) {
				continue;
			}
			rfbLog("  closing client %s (no useNewFBSize"
			    " support).\n", cl->host);
			rfbCloseClient(cl);
			rfbClientConnectionGone(cl);
		}
		rfbReleaseClientIterator(iter);
	}
	
	/* default, resize, and newfbsize create a new fb: */
	rfbLog("check_xrandr_event: trying to create new framebuffer...\n");
	if (new_x < wdpy_x || new_y < wdpy_y) {
		check_black_fb();
	}
	do_new_fb(1);
	rfbLog("check_xrandr_event: fb       WxH: %dx%d\n", wdpy_x, wdpy_y);
}
Esempio n. 5
0
static void init_freqtab(char *file) {
	char *p, *q, *dir, *file2;
	char line[1024], inc[1024];
	char *text, *str;
	int size = 0, maxn, extra, currn;
	FILE *in1, *in2;
	static int v = 1;
	if (quiet) {
		v = 0;
	}

	/* YUCK */

	dir = strdup(file);
	q = strrchr(dir, '/');
	if (q) {
		*(q+1) = '\0';
	} else {
		free(dir);
		dir = strdup("./");
	}
	file2 = (char *) malloc(strlen(dir) + 1024 + 1);
	in1 = fopen(file, "r");
	if (in1 == NULL) {
		rfbLog("error opening freqtab: %s\n", file);
		clean_up_exit(1);
	}
	if (v) fprintf(stderr, "loading frequencies from: %s\n", file);
	while (fgets(line, 1024, in1) != NULL) {
		char *lb;
		char line2[1024];
		size += strlen(line);
		lb = lblanks(line);
		if (strstr(lb, "#include") == lb && 
		    sscanf(lb, "#include %s", inc) == 1) {
			char *q, *s = inc;
			if (s[0] == '"') {
				s++;
			}
			q = strrchr(s, '"');
			if (q) {
				*q = '\0';
			}
			sprintf(file2, "%s%s", dir, s);
			in2 = fopen(file2, "r");
			if (in2 == NULL) {
				rfbLog("error opening freqtab include: %s %s\n", line, file2);
				clean_up_exit(1);
			}
			if (v) fprintf(stderr, "loading frequencies from: %s\n", file2);
			while (fgets(line2, 1024, in2) != NULL) {
				size += strlen(line2);
			}
			fclose(in2);
		}
	}
	fclose(in1);

	size = 4*(size + 10000);

	text = (char *) malloc(size);

	text[0] = '\0';

	in1 = fopen(file, "r");
	if (in1 == NULL) {
		rfbLog("error opening freqtab: %s\n", file);
		clean_up_exit(1);
	}
	while (fgets(line, 1024, in1) != NULL) {
		char *lb;
		char line2[1024];
		lb = lblanks(line);
		if (lb[0] == '[') {
			strcat(text, lb);
		} else if (strstr(lb, "freq")) {
			strcat(text, lb);
		} else if (strstr(lb, "#include") == lb && 
		    sscanf(lb, "#include %s", inc) == 1) {
			char *lb2;
			char *q, *s = inc;
			if (s[0] == '"') {
				s++;
			}
			q = strrchr(s, '"');
			if (q) {
				*q = '\0';
			}
			sprintf(file2, "%s%s", dir, s);
			in2 = fopen(file2, "r");
			if (in2 == NULL) {
				rfbLog("error opening freqtab include: %s %s\n", line, file2);
				clean_up_exit(1);
			}
			while (fgets(line2, 1024, in2) != NULL) {
				lb2 = lblanks(line2);
				if (lb2[0] == '[') {
					strcat(text, lb2);
				} else if (strstr(lb2, "freq")) {
					strcat(text, lb2);
				}
				if ((int) strlen(text) > size/2) {
					break;
				}
			}
			fclose(in2);
		}
		if ((int) strlen(text) > size/2) {
			break;
		}
	}
	fclose(in1);

	if (0) fprintf(stderr, "%s", text);

	str = strdup(text);
	p = strtok(str, "\n");
	maxn = -1;
	extra = 0;
	while (p) {
		if (p[0] == '[') {
			int ok = 1;
			q = p+1;	
			while (*q) {
				if (*q == ']') {
					break;
				}
				if (! isdigit((unsigned char) (*q))) {
					if (0) fprintf(stderr, "extra: %s\n", p);
					extra++;
					ok = 0;
					break;
				}
				q++;
			}
			if (ok) {
				int n;
				if (sscanf(p, "[%d]", &n) == 1)  {
					if (n > maxn) {
						maxn = n;
					}
					if (0) fprintf(stderr, "maxn:  %d %d\n", maxn, n);
				}
			}
			
		}
		p = strtok(NULL, "\n");
	}
	free(str);

	str = strdup(text);
	p = strtok(str, "\n");
	extra = 0;
	currn = 0;
	if (v) fprintf(stderr, "\nname\tstation\tfreq (KHz)\n");
	while (p) {
		if (p[0] == '[') {
			int ok = 1;
			strncpy(line, p, 100);
			q = p+1;	
			while (*q) {
				if (*q == ']') {
					break;
				}
				if (! isdigit((unsigned char) (*q))) {
					extra++;
					currn = maxn + extra;
					ok = 0;
					break;
				}
				q++;
			}
			if (ok) {
				int n;
				if (sscanf(p, "[%d]", &n) == 1)  {
					currn = n;
				}
			}
		}
		if (strstr(p, "freq") && (q = strchr(p, '=')) != NULL) {
			int n;
			q = lblanks(q+1);
			if (sscanf(q, "%d", &n) == 1) {
				if (currn >= 0 && currn < CHANNEL_MAX) {
					if (v) fprintf(stderr, "%s\t%d\t%d\n", line, currn, n);
					custom_freq[currn] = (unsigned long) n;
					if (last_freq == 0) {
						last_freq = custom_freq[currn];
					}
				}
			}
		}
		p = strtok(NULL, "\n");
	}
	if (v) fprintf(stderr, "\n");
	v = 0;
	free(str);
	free(text);
	free(dir);
	free(file2);
}
Esempio n. 6
0
static int XIOerr(Display *d) {
	static int reopen = 0, rmax = 1;
	X_UNLOCK;

	if (getenv("X11VNC_REOPEN_DISPLAY")) {
		rmax = atoi(getenv("X11VNC_REOPEN_DISPLAY"));
	}

#if !NO_X11
	if (reopen < rmax && getenv("X11VNC_REOPEN_DISPLAY")) {
		int db = getenv("X11VNC_REOPEN_DEBUG") ? 1 : 0;
		int sleepmax = 10, i;
		Display *save_dpy = dpy;
		char *dstr = strdup(DisplayString(save_dpy));
		reopen++;	
		if (getenv("X11VNC_REOPEN_SLEEP_MAX")) {
			sleepmax = atoi(getenv("X11VNC_REOPEN_SLEEP_MAX"));
		}
		rfbLog("*** XIO error: Trying to reopen[%d/%d] display '%s'\n", reopen, rmax, dstr);
		rfbLog("*** XIO error: Note the reopened state may be unstable.\n");
		for (i=0; i < sleepmax; i++) {
			usleep (1000 * 1000);
			dpy = XOpenDisplay_wr(dstr);
			rfbLog("dpy[%d/%d]: %p\n", i+1, sleepmax, dpy);
			if (dpy) {
				break;
			}
		}
		last_open_xdisplay = time(NULL);
		if (dpy) {
			rfbLog("*** XIO error: Reopened display '%s' successfully.\n", dstr);
			if (db) rfbLog("*** XIO error: '%s' 0x%x\n", dstr, dpy);
			scr = DefaultScreen(dpy);
			rootwin = RootWindow(dpy, scr);
			if (db) rfbLog("*** XIO error: disable_grabserver\n");
			disable_grabserver(dpy, 0);
			if (db) rfbLog("*** XIO error: xrecord\n");
			zerodisp_xrecord();
			initialize_xrecord();
			if (db) rfbLog("*** XIO error: xdamage\n");
			create_xdamage_if_needed(1);
			if (db) rfbLog("*** XIO error: do_new_fb\n");
			if (using_shm) {
				if (db) rfbLog("*** XIO error: clean_shm\n");
				clean_shm(1);
			}
			do_new_fb(1);
			if (db) rfbLog("*** XIO error: check_xevents\n");
			check_xevents(1);

			/* sadly, we can never return... */
			if (db) rfbLog("*** XIO error: watch_loop\n");
			watch_loop();
			clean_up_exit(1);	
		}
	}
#endif

	interrupted(-1);

	if (d) {} /* unused vars warning: */

	return (*XIOerr_def)(d);
}
Esempio n. 7
0
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
}
Esempio n. 8
0
void setup_stunnel(int rport, int *argc, char **argv) {
	int i, xport = 0, hport = 0, xhport = 0;

	if (! rport && argc && argv) {
		for (i=0; i< *argc; i++) {
			if (argv[i] && !strcmp(argv[i], "-rfbport")) {
				if (i < *argc - 1) {
					rport = atoi(argv[i+1]);
				}
			}
		}
	}

	if (! rport) {
		/* we do our own autoprobing then... */
		rport = find_free_port(5900, 5999);
		if (! rport) {
			goto stunnel_fail;
		}
	}

	xport = find_free_port(5950, 5999);
	if (! xport) {
		goto stunnel_fail; 
	}

	if (https_port_num > 0) {
		hport = https_port_num;
	}

	if (! hport && argc && argv) {
		for (i=0; i< *argc; i++) {
			if (argv[i] && !strcmp(argv[i], "-httpport")) {
				if (i < *argc - 1) {
					hport = atoi(argv[i+1]);
				}
			}
		}
	}

	if (! hport && http_try_it) {
		hport = find_free_port(rport-100, rport-1);
		if (! hport) {
			goto stunnel_fail;
		}
	}
	if (hport) {
		xhport = find_free_port(5850, 5899);
		if (! xhport) {
			goto stunnel_fail; 
		}
		stunnel_http_port = hport;
	}
	

	if (start_stunnel(rport, xport, hport, xhport)) {
		int tweaked = 0;
		char tmp[30];
		sprintf(tmp, "%d", xport);
		if (argc && argv) {
			for (i=0; i < *argc; i++) {
				if (argv[i] && !strcmp(argv[i], "-rfbport")) {
					if (i < *argc - 1) {
						/* replace orig value */
						argv[i+i] = strdup(tmp); 
						tweaked = 1;
						break;
					}
				}
			}
			if (! tweaked) {
				i = *argc;
				argv[i] = strdup("-rfbport");
				argv[i+1] = strdup(tmp);
				*argc += 2;
				got_rfbport = 1;
				got_rfbport_val = atoi(tmp);
			}
		}
		stunnel_port = rport;
		ssl_initialized = 1;
		return;
	}

	stunnel_fail:
	rfbLog("failed to start stunnel.\n");
	clean_up_exit(1);
}