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