1 
2 /*
3  * Copyright (c) 2002-2006 Tomas Svensson <ts@codepix.com>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
20  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #define _POSIX_PII_SOCKET /* for Tru64 UNIX 5.1 */
30 
31 #define TLSWRAP_VERSION_TEXT "v1.04"
32 
33 #ifdef WIN32
34 #include "stdafx.h"
35 #endif
36 
37 #include "conf.h"
38 
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <fcntl.h>
42 #include <signal.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 
47 #ifdef WIN32
48 #define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
49 #include <Winsock2.h>
50 #include <windows.h>
51 #include <process.h>    /* _beginthread, _endthread */
52 #include <direct.h>
53 #define snprintf _snprintf
54 #define strcasecmp _stricmp
55 #define strncasecmp _strnicmp
56 #define chdir _chdir
57 #define mkdir _mkdir
58 #define getcwd _getcwd
59 typedef int socklen_t;
60 #ifdef WIN64
61 typedef   __int64 ssize_t;
62 #else
63 typedef   __int32 ssize_t;
64 #endif
65 #define ECONNREFUSED WSAECONNREFUSED
66 #define EINPROGRESS WSAEINPROGRESS
67 #define EWOULDBLOCK WSAEWOULDBLOCK
68 #define ECONNRESET WSAECONNRESET
69 int write(SOCKET s, void *buf, int len);
70 int read(SOCKET s, void *buf, int len);
71 #define close closesocket
72 char *srv_name = "TLSWrap";
73 char *srv_name2 = "TLSWrap Service";
74 char *srv_desc = "TLSWrap is a TLS/SSL FTP wrapper";
75 #else
76 #include <sys/resource.h>
77 #include <sys/time.h>
78 #include <sys/errno.h>
79 #include <sys/socket.h>
80 #include <netdb.h>
81 #include <unistd.h>
82 #endif
83 
84 #include "tlswrap.h"
85 #include "network.h"
86 #include "misc.h"
87 #include "parse.h"
88 #include "tls.h"
89 #include "config.h"
90 
91 char	*cfg_tlsrsafile;
92 char	*cfg_tlsciphers;
93 
94 int		debug;
95 int		sec_mode;
96 int		dns_write_pipe, dns_read_pipe, pipe01[2], pipe02[2];
97 
98 #ifdef WIN32
99 int		in_service;
100 struct	parm serv_param;
101 #endif
102 
103 
104 #ifdef HAVE_LIBWRAP
105 #include <tcpd.h>
106 
107 int allow_severity;
108 int deny_severity;
109 #endif
110 
111 int main2(int argc, char *argv[]);
112 
main(int argc,char * argv[])113 int main(int argc, char *argv[])
114 {
115 #if defined(WIN32) && !defined(WIN98)
116 	SERVICE_TABLE_ENTRY servicetable[]=
117 	{
118 		{srv_name,(LPSERVICE_MAIN_FUNCTION)service_main},
119 		{NULL,NULL}
120 	};
121 	serv_param.argc = argc;
122 	serv_param.argv = argv;
123 	in_service = 0;
124 	if ((argc >= 2) && !strcmp(argv[1], "-S")) {
125 		in_service = 1;
126 		StartServiceCtrlDispatcher(servicetable);
127 	}
128 	else
129 #endif
130 	return main2(argc, argv);
131 }
132 
133 #if defined(WIN32) && !defined(WIN98)
service_execution_thread(LPDWORD param)134 DWORD service_execution_thread(LPDWORD param) {
135 	return main2(serv_param.argc, serv_param.argv);
136 }
137 #endif
138 
main2(int argc,char * argv[])139 int main2(int argc, char *argv[]) {
140 #ifndef WIN32
141 	struct	sigaction sact;
142 	pid_t 	childpid;
143 	struct	rlimit rlimit;
144 	int		flags;
145 #ifndef __CYGWIN__
146 	char	fakebuf[1];
147 	int		sock_err;
148 	socklen_t sock_errlen;
149 #endif
150 #else
151 	WORD	wVersionRequested;
152 	WSADATA wsaData;
153 	char 	port[6] ;//, tport[6];
154 	SOCKET	temp_sock;
155 	int		conn_res;
156 	unsigned int lport;
157 	SOCKET  arg[2];
158 	unsigned long sockarg;
159 #endif
160 #if defined(WIN32) || defined(__CYGWIN__)
161 	fd_set	eset;
162 #endif
163 	char	buffer[NI_MAXHOST];
164 	int 	listen_fd;
165 	int		idx;
166 	int		i, sel, newsock;
167 	int		remove_this,  serv_write;
168 	char 	cfg_listenport[6];
169 	char	cfg_egdsock[NI_MAXHOST];
170 	char	cfg_listenhost[NI_MAXHOST];
171 	char	cfg_instopt[NI_MAXHOST];
172 	unsigned int cfg_max_users;
173 	fd_set  rset, wset;
174 	struct	sockaddr sockaddr;
175 	socklen_t	socklen;
176 	struct	user_data *ud;
177 	struct	dns_msg dns;
178 	unsigned int	tcpbufsize, tcpsndlowat;
179 	ssize_t bytes, bytesW;
180 	char	token[6];
181 	char	certspath[1024];
182 	char	ucertspath[1024];
183 	char	cfg_cafile[1024];
184 	char	crlfile[1024];
185 	int		conn_err, serv_remove, serv_install, key_wait;
186 	char remoteip[NI_MAXHOST];
187 	if ( (cfg_tlsciphers = (char*)malloc(1024)) == NULL)
188 		exit(1);
189 
190 #ifndef WIN32
191 	rlimit.rlim_cur = RLIM_INFINITY;
192 	rlimit.rlim_max = RLIM_INFINITY;
193 	setrlimit(RLIMIT_CORE, &rlimit);
194 #else
195 	wVersionRequested = MAKEWORD(2,0);
196 
197 	if (WSAStartup(wVersionRequested, &wsaData)) {
198 		MessageBox(NULL, "Can't initialize WinSock 2.0", "TLSWrap", MB_OK |
199 			MB_ICONERROR);
200 		exit(0);
201 	}
202 	if(!SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE)) {
203 		printf("Can't set control handler\n");
204 	}
205 
206 #endif
207 
208 	read_config(argc, argv, &cfg_max_users, cfg_listenport,
209 	    sizeof(cfg_listenport), &debug,
210 	    cfg_egdsock, sizeof(cfg_egdsock), cfg_tlsciphers,
211 	    1024, &tcpbufsize, &tcpsndlowat, cfg_listenhost,
212 	    sizeof(cfg_listenhost), token, sizeof(token), &sec_mode,
213 	    certspath, sizeof(certspath), &serv_install, &serv_remove, &key_wait,
214 		cfg_instopt, sizeof(cfg_instopt), ucertspath, sizeof(ucertspath),
215 		cfg_cafile, sizeof(cfg_cafile), crlfile, sizeof(crlfile));
216 
217 	if ( (ud = (struct user_data*)malloc(cfg_max_users *
218 		    sizeof(struct user_data))) == NULL) {
219 		fprintf(stderr,"can't malloc user_data");
220 		exit(1);
221 	}
222 
223 #if defined(WIN32) && !defined(WIN98)
224 	if (serv_install) {
225 		if(_getcwd(buffer, NI_MAXHOST) == NULL )
226 			perror("_getcwd error" );
227 		install_service(buffer, cfg_instopt, key_wait);
228 	} else if (serv_remove)
229 		remove_service(key_wait);
230 #endif
231 
232 	if (1) { //if (sec_mode > 0) {
233 #ifndef WIN32
234 		umask(077);
235 #endif
236 		if (certspath[0] != '\0') {
237 			if (chdir(certspath))
238 				sys_err("unable to access certs dir");
239 		} else {
240 			if (chdir("certs")) {
241 #ifndef WIN32
242 				if (mkdir("certs", 0700))
243 #else
244 				if (mkdir("certs"))
245 #endif
246 					sys_err("unable to create certs dir");
247 				if (chdir("certs"))
248 					sys_err("unable to access certs dir");
249 			}
250 			if (getcwd(certspath, sizeof(certspath)) == NULL)
251 				sys_err("certspath getcwd");
252 		}
253 	}
254 
255 	if (debug) {
256 		printf("certspath = %s\nucertspath = %s\n", certspath, ucertspath);
257 	}
258 	tls_init(cfg_egdsock);
259 
260 #ifndef WIN32
261 	sact.sa_handler = SIG_IGN;
262 	sigemptyset(&sact.sa_mask);
263 	sact.sa_flags = 0;
264 	sigaction(SIGPIPE, &sact, NULL);
265 #endif
266 
267 #ifdef HAVE_SETPROCTITLE
268   	setproctitle("tlswrap");
269 #endif
270 
271 #ifndef WIN32
272 
273 	if (pipe(pipe01)) sys_err("pipe01");
274 	if (pipe(pipe02)) sys_err("pipe02");
275 
276 	if ( (childpid = fork()) == 0) {
277 		close(pipe01[1]);
278 		close(pipe02[0]);
279 		dns_helper(pipe01[0], pipe02[1]);
280 	} else {
281 		close(pipe01[0]);
282 		close(pipe02[1]);
283 	}
284 
285 	dns_write_pipe = pipe01[1];
286 	dns_read_pipe  = pipe02[0];
287 
288 	flags = fcntl(dns_write_pipe, F_GETFL);
289 	fcntl(dns_write_pipe, F_SETFL, flags | O_NONBLOCK);
290     flags = fcntl(dns_read_pipe, F_GETFL);
291 	fcntl(dns_read_pipe, F_SETFL, flags | O_NONBLOCK);
292 
293 #else
294 	port[0] = '\0';
295 	temp_sock = setup_listen(5, "127.0.0.1", port, sizeof(port));
296 	if (debug)
297 		printf("listening to port %s for pipe setup\n", port);
298 	pipe01[0] = setup_connect("127.0.0.1", port, &lport, &conn_res);
299 	if (conn_res == 0) { /* connected OK */
300 		if ((pipe01[1] = accept(temp_sock, NULL, NULL)) == INVALID_SOCKET)
301 			sys_err("setup error for fake pipe");
302 	} else if (conn_res != 1) sys_err("local pipe connect1");
303 	FD_ZERO(&rset);
304 	FD_SET(temp_sock, &rset);
305 	select(1, &rset, NULL, NULL, NULL);
306 	//if (FD_ISSET(pipe01[0], &wset)) {
307 	if (FD_ISSET(temp_sock, &rset)) {
308 		if ((pipe01[1] = accept(temp_sock, NULL, NULL)) == INVALID_SOCKET){
309 			printf("setup error for fake pipe01: %d\n", WSAGetLastError());
310 			exit(0);
311 		}
312 	} else sys_err("could not connect to local pipe 1");
313 
314 
315 	pipe02[1] = setup_connect("127.0.0.1", port, &lport, &conn_res);
316 	if (conn_res == 0) { /* connected OK */
317 		if ((pipe02[0] = accept(temp_sock, NULL, NULL)) == INVALID_SOCKET)
318 			sys_err("setup error for fake pipe");
319 	} else if (conn_res != 1) sys_err("local pipe connect2");
320 	FD_ZERO(&rset);
321 	FD_SET(temp_sock, &rset);
322 	select(1, &rset, NULL, NULL, NULL);
323 	if (FD_ISSET(temp_sock, &rset)) {
324 		if ((pipe02[0] = accept(temp_sock, NULL, NULL)) == INVALID_SOCKET) {
325 			printf("setup error for fake pipe02: %d\n", WSAGetLastError());
326 			exit(0);
327 		}
328 	} else sys_err("could not connect to local pipe 2");
329 
330 	if (closesocket(temp_sock) == SOCKET_ERROR)
331 		printf("error closing listening socket because %d\n", WSAGetLastError());
332 
333 	dns_write_pipe = pipe01[1];
334 	dns_read_pipe  = pipe02[0];
335 
336 	/* Turn off non-blocking for sockets to be used in the DNS helper */
337 
338 	sockarg = 0;
339 
340 	if (ioctlsocket(pipe01[0], FIONBIO, &sockarg) ==  SOCKET_ERROR) {
341 		printf("ioctlsocket 1 failed because %d\n", WSAGetLastError());
342 		exit(-1);
343 	}
344 
345 	if (ioctlsocket(pipe02[1], FIONBIO, &sockarg) ==  SOCKET_ERROR) {
346 		printf("ioctlsocket 2 failed because %d\n", WSAGetLastError());
347 		exit(-1);
348 	}
349 	arg[0] = pipe01[0];
350 	arg[1] = pipe02[1];
351 
352 	_beginthread((dns_helper), 0, &arg);
353 
354 #endif /* WIN32 */
355 
356 	/* Do blocking DNS requests before this (if any) */
357 
358 	init_ud(ud, cfg_max_users);
359 
360 	listen_fd = setup_listen(5, cfg_listenhost, cfg_listenport, 0);
361 
362 	fprintf(stderr,
363 	    "TLSWrap %s (c) 2002-2006 Tomas Svensson <ts@codepix.com>\n", TLSWRAP_VERSION_TEXT);
364 	fprintf(stderr, "Servicing up to %u clients on %s:%s\n", cfg_max_users, cfg_listenhost, cfg_listenport);
365 #if !defined __CYGWIN__ && !defined WIN32
366 #ifdef __HAVE_DAEMON
367 	if (!debug)
368 		daemon(0 ,0);
369 #else
370 	if (!debug) {
371 		if ( (childpid = fork()) < 0)
372 			sys_err("fork()");
373 		else if (childpid != 0) {
374 			fprintf(stderr, "Running as process %u\n", (unsigned int)childpid);
375 			exit(0); /* parent */
376 		}
377 		(void)setsid();
378 		if (certspath[0] == '\0')
379 			chdir("/");
380 	}
381 #endif /* !HAVE_DAEMON */
382 #endif /* !__CYGWIN__ */
383 
384  	for(;;) {
385 		FD_ZERO(&rset);
386 		FD_ZERO(&wset);
387 #if defined(WIN32) || defined(__CYGWIN__)
388 		FD_ZERO(&eset);
389 #endif
390 		FD_SET(listen_fd, &rset);
391 		FD_SET(dns_read_pipe, &rset);
392 
393 		for(i = 0; i < cfg_max_users ; i++) {
394 			if (ud[i].user_fd != -1) {
395 				/* If there is room in the buffer, read from the user control connection */
396 				if (ud[i].u2s_i < &ud[i].u2s_buf[U2S_SIZE]) {
397 					FD_SET(ud[i].user_fd, &rset);
398 				}
399 				/* If there is room in the buffer and we are connected,
400 					read from the server control connection */
401 				if ((ud[i].connected == CONN_YES) &&
402 					(ud[i].s2u_i < &ud[i].s2u_buf[S2U_SIZE])) {
403 					FD_SET(ud[i].serv_fd, &rset);
404 				}
405 				else if (ud[i].connected == CONN_IN_PROG) {
406 #if defined(WIN32) || defined(__CYGWIN__)
407 					FD_SET(ud[i].serv_fd, &eset);
408 #else
409 					FD_SET(ud[i].serv_fd, &rset);
410 #endif
411 					FD_SET(ud[i].serv_fd, &wset);
412 				}
413 				if (ud[i].data_connected == CONN_IN_PROG) {
414 #if defined(WIN32) || defined(__CYGWIN__)
415 					FD_SET(ud[i].serv_data_fd, &eset);
416 #else
417 					FD_SET(ud[i].serv_data_fd, &rset);
418 #endif
419 					FD_SET(ud[i].serv_data_fd, &wset);
420 				} else if (ud[i].data_connected == CONN_DATA_OK) {
421 					if (ud[i].dc2s_i <
422 					    &ud[i].dc2s_buf[DBUF_SIZE])
423 					 	if (ud[i].user_data_close != CLOSE_READ)
424 							FD_SET(ud[i].user_data_fd, &rset);
425 					if (ud[i].ds2c_i <
426 					    &ud[i].ds2c_buf[DBUF_SIZE])
427 						if  (ud[i].serv_data_close != CLOSE_READ)
428 							FD_SET(ud[i].serv_data_fd, &rset);
429 					if (ud[i].dc2s_i != ud[i].dc2s_o)
430 						if (ud[i].serv_data_close != CLOSE_WRITE)
431 							FD_SET(ud[i].serv_data_fd, &wset);
432 					if (ud[i].ds2c_i != ud[i].ds2c_o)
433 						if (ud[i].user_data_close != CLOSE_WRITE)
434 							FD_SET(ud[i].user_data_fd, &wset);
435 				} else if (ud[i].data_connected == CONN_DATA_LISTEN) {
436 					FD_SET(ud[i].user_data_fd, &rset);
437 					if (debug)
438 						printf("setting fd %d for conn_data_listen\n",ud[i].user_data_fd);
439 				}
440 
441 				if ((ud[i].connected == CONN_YES) && (ud[i].u2s_i != ud[i].u2s_o)) {
442 					FD_SET(ud[i].serv_fd, &wset);
443 				}
444 				if ((ud[i].u2s_i - ud[i].u2s_o) < 0)
445 					sys_err("bug");
446 				if (ud[i].s2u_i != ud[i].s2u_o) {
447 					if ((memchr(ud[i].s2u_o, '\n', ud[i].s2u_i-ud[i].s2u_o) != NULL) ||
448 						(ud[i].s2u_i == &ud[i].s2u_buf[S2U_SIZE]))
449 						//(memchr(ud[i].s2u_o, '\n', ud[i].s2u_i-ud[i].s2u_o) != NULL)  /* should be? */
450 						FD_SET(ud[i].user_fd, &wset); // memchr crap again
451 				}
452 
453 
454 				if (ud[i].retry)
455 					FD_SET(ud[i].user_fd, &wset);
456 				if (ud[i].retry_data)
457 					FD_SET(ud[i].user_data_fd, &wset);
458 
459 				/* TLS connection negotiation */
460 
461 				if (ud[i].ssl_ctrl_fd_mode == TLS_READ) {
462 					if (debug)
463 						printf("TLS_READ: fd = %d\n", ud[i].serv_fd);
464 					FD_SET(ud[i].serv_fd, &rset);
465 					FD_CLR(ud[i].serv_fd, &wset);
466 				} else if (ud[i].ssl_ctrl_fd_mode == TLS_WRITE) {
467 					FD_SET(ud[i].serv_fd, &wset);
468 					FD_CLR(ud[i].serv_fd, &rset);
469 				}
470 
471 				if (ud[i].ssl_data_fd_mode == TLS_READ) {
472 					if (debug)
473 						printf("setting serv_data_fd (%d) in rset for TLS_READ\n", ud[i].serv_data_fd);
474 					FD_SET(ud[i].serv_data_fd, &rset);
475 					FD_CLR(ud[i].serv_data_fd, &wset);
476 				} else if (ud[i].ssl_data_fd_mode == TLS_WRITE) {
477 					if (debug)
478 						printf("setting serv_data_fd (%d) in wset for TLS_WRITE\n", ud[i].serv_data_fd);
479 					FD_SET(ud[i].serv_data_fd, &wset);
480 					FD_CLR(ud[i].serv_data_fd, &rset);
481 				}
482 			} /* if fd */
483 
484 		} /* for */
485 
486 		/*
487 		max_fd = find_max_fd((dns_read_pipe > listen_fd) ?
488 		    dns_read_pipe : listen_fd, ud, cfg_max_users);
489 		 max_fd = find_max_fd(&rset, &wset);
490 
491 		if (debug)
492 			printf("max_fd = %d\n",max_fd);
493 		*/
494 #if 0
495 
496 		if (debug) {
497 			printf("listening for:\n");
498 			i = 0;
499 			if (FD_ISSET(ud[i].user_fd, &rset))
500 				printf("user_fd readable\n");
501 			if (FD_ISSET(ud[i].user_fd, &wset))
502 				printf("user_fd writable\n");
503 			if (FD_ISSET(ud[i].serv_fd, &rset))
504 				printf("serv_fd readable\n");
505 			if (FD_ISSET(ud[i].serv_fd, &wset))
506 				printf("serv_fd writable\n");
507 			if (FD_ISSET(ud[i].user_data_fd, &rset))
508 				printf("user_data_fd (%d) readable\n", ud[i].user_data_fd);
509 			if (FD_ISSET(ud[i].user_data_fd, &wset))
510 				printf("user_data_fd (%d) writable\n", ud[i].user_data_fd);
511 			if (FD_ISSET(ud[i].serv_data_fd, &rset))
512 				printf("serv_data_fd (%d) readable\n", ud[i].serv_data_fd);
513 			if (FD_ISSET(ud[i].serv_data_fd, &wset))
514 				printf("serv_data_fd (%d) writable\n", ud[i].serv_data_fd);
515 #ifdef WIN32
516 			if (FD_ISSET(ud[i].serv_data_fd, &eset))
517 				printf("serv_data_fd (%d) exception\n", ud[i].serv_data_fd);
518 			if (FD_ISSET(ud[i].serv_fd, &eset))
519 				printf("serv_fd (%d) exception\n", ud[i].serv_fd);
520 #endif
521 		}
522 #endif
523 
524 #if defined(WIN32) || defined(__CYGWIN__)
525 		sel = select(FD_SETSIZE, &rset, &wset, &eset, NULL);
526 #else
527 		sel = select(FD_SETSIZE, &rset, &wset, NULL, NULL);
528 #endif
529 #if 0
530 		if (debug) {
531 			printf("result is :\n");
532 			i = 0;
533 			if (FD_ISSET(ud[i].user_fd, &rset))
534 				printf("user_fd readable\n");
535 			if (FD_ISSET(ud[i].user_fd, &wset))
536 				printf("user_fd writable\n");
537 			if (FD_ISSET(ud[i].serv_fd, &rset))
538 				printf("serv_fd readable\n");
539 			if (FD_ISSET(ud[i].serv_fd, &wset))
540 				printf("serv_fd writable\n");
541 			if (FD_ISSET(ud[i].user_data_fd, &rset))
542 				printf("user_fd readable\n");
543 			if (FD_ISSET(ud[i].user_data_fd, &wset))
544 				printf("user_fd writable\n");
545 			if (FD_ISSET(ud[i].serv_data_fd, &rset))
546 				printf("serv_fd readable\n");
547 			if (FD_ISSET(ud[i].serv_data_fd, &wset))
548 				printf("serv_fd writable\n");
549 #ifdef WIN32
550 			if (FD_ISSET(ud[i].serv_data_fd, &eset))
551 				printf("serv_data_fd (%d) exception\n", ud[i].serv_data_fd);
552 			if (FD_ISSET(ud[i].serv_fd, &eset))
553 				printf("serv_fd (%d) exception\n", ud[i].serv_fd);
554 #endif
555 			if (FD_ISSET(dns_read_pipe, &rset))
556 				printf("dns read pipe\n");
557 			if (FD_ISSET(listen_fd, &rset))
558 				printf("listen_fd\n");
559 			printf("---------------------\n");
560 		}
561 		if (sel == -1) {
562 #ifdef WIN32
563 			printf("select failed because %d\n", WSAGetLastError());
564 #endif
565 			sys_err("select");
566 		}
567 #endif
568 		if (debug)
569 			printf("selected\n");
570 		if (FD_ISSET(dns_read_pipe, &rset)) {
571 			if ( (bytes = read(dns_read_pipe, &dns, sizeof(dns)))
572 			    == sizeof(dns) ) {
573 				if ((ud[dns.ud].user_fd != -1) && (ud[dns.ud].connected == CONN_DNS)) {
574 					ud[dns.ud].serv_dns = dns; /* use for EPSV later */
575 					setup_connect_2(&ud[dns.ud], &dns, 0);
576 				}
577 			} else {
578 #ifdef WIN32
579 					printf("Exiting...\n");
580 					WSACleanup();
581 					if (in_service)
582 						_endthread();
583 					else
584 						exit(0);
585 #endif
586 				sys_err("child died");
587 			}
588 		}
589 		if (FD_ISSET(listen_fd, &rset)) {
590 			memset(&sockaddr, 0, sizeof(sockaddr));
591 			socklen = sizeof(sockaddr);
592 			if ( (newsock = accept(listen_fd, &sockaddr, &socklen)) != -1) {
593 				idx = find_free_slot(ud, cfg_max_users);
594 				if (idx==-1) {
595 					write(newsock, "No more users allowed.\r\n", 24);
596 					close(newsock);
597 				} else {
598 					memset(&ud[idx], 0, sizeof(struct user_data));
599 					ud[idx].u2s_i = ud[idx].u2s_o = ud[idx].u2s_buf;
600 					ud[idx].s2u_i = ud[idx].s2u_o = ud[idx].s2u_buf;
601 					ud[idx].user_ptr = ud[idx].user_input;
602 					ud[idx].serv_ptr = ud[idx].serv_input;
603 					ud[idx].connected = CONN_NO;
604 					ud[idx].data_connected = CONN_NO;
605 					ud[idx].serv_status = SERV_NONE;
606 					ud[idx].serv_data_fd = -1;
607 					ud[idx].user_fd = newsock;
608 					ud[idx].ssl_data_fd_mode = TLS_NONE;
609 					ud[idx].ssl_ctrl_fd_mode = TLS_NONE;
610 					ud[idx].sec_level = sec_mode;
611 					if (debug)
612 						printf("connected to user\n");
613 					snprintf(buffer, sizeof(buffer), "220 TLSWrap FTP Proxy Server (%s) ready.\r\n", TLSWRAP_VERSION_TEXT);
614 					print_to_ud(&ud[idx], buffer);
615 				}
616 			} /*else {
617 				printf("accept failed\n");
618 			}*/
619 		}
620 		for(i = 0; i < cfg_max_users; i++) {
621 			remove_this = 0;
622 			serv_write = 0;
623 			if (ud[i].user_fd != -1) {
624 
625 				/* TLS section */
626 
627 				if (ud[i].serv_status == SERV_TLS) {
628 					if (debug)
629 						printf("checking TLS status\n");
630 					if ( ((ud[i].ssl_ctrl_fd_mode == TLS_READ) && FD_ISSET(ud[i].serv_fd, &rset)) ||
631 						((ud[i].ssl_ctrl_fd_mode == TLS_WRITE) && FD_ISSET(ud[i].serv_fd, &wset)) ) {
632 						tls_auth_cont(&ud[i], 0);
633 						continue;
634 					}
635 				}
636 				if (ud[i].data_connected == CONN_DATA_TLS) {
637 					if (debug)
638 						printf("checking conn_data_tls\n");
639 					if ( ((ud[i].ssl_data_fd_mode == TLS_READ) && FD_ISSET(ud[i].serv_data_fd, &rset)) ||
640 						((ud[i].ssl_data_fd_mode == TLS_WRITE) && FD_ISSET(ud[i].serv_data_fd, &wset)) ) {
641 						tls_auth_cont(&ud[i], 1);
642 						continue;
643 					}
644 				}
645 
646 				/* TLS fd swapping */
647 
648 				if (ud[i].tls_status & TLS_CTRL) {
649 					if (ud[i].ssl_ctrl_fd_mode == TLS_READ && FD_ISSET(ud[i].serv_fd, &rset) &&
650 				      ud[i].ssl_ctrl_func == TLS_WRITE) {
651 						FD_SET(ud[i].serv_fd, &wset);
652 						FD_CLR(ud[i].serv_fd, &rset);
653 					} else if (ud[i].ssl_ctrl_fd_mode == TLS_WRITE && FD_ISSET(ud[i].serv_fd, &wset) &&
654 				     ud[i].ssl_ctrl_func == TLS_READ) {
655 						FD_SET(ud[i].serv_fd, &rset);
656 						FD_CLR(ud[i].serv_fd, &wset);
657 					}
658 				}
659 
660 				if (ud[i].tls_status & TLS_DATA) {
661 					if (ud[i].ssl_data_fd_mode == TLS_READ && FD_ISSET(ud[i].serv_data_fd, &rset) &&
662 					  ud[i].ssl_data_func == TLS_WRITE) {
663 						FD_SET(ud[i].serv_data_fd, &wset);
664 						FD_CLR(ud[i].serv_data_fd, &rset);
665 					} else if ( ud[i].ssl_data_fd_mode == TLS_WRITE && FD_ISSET(ud[i].serv_data_fd, &wset) &&
666 						ud[i].ssl_data_func == TLS_READ) {
667 						FD_SET(ud[i].serv_data_fd, &rset);
668 						FD_CLR(ud[i].serv_data_fd, &wset);
669 					}
670 				}
671 
672 				/* Read Section */
673 
674 
675 				if (ud[i].connected == CONN_YES) {
676 					if ((ud[i].retry && FD_ISSET(ud[i].user_fd,  &wset)) ||
677 					  FD_ISSET(ud[i].serv_fd, &rset)) {
678 						if ((debug) && (ud[i].retry))
679 							printf("retry set\n");
680 						if (ud[i].tls_status & TLS_CTRL)
681 							bytes = tls_read(&ud[i], ud[i].s2u_i, &ud[i].s2u_buf[S2U_SIZE] - ud[i].s2u_i,0);
682 						else
683 							bytes = read(ud[i].serv_fd, ud[i].s2u_i, &ud[i].s2u_buf[S2U_SIZE] - ud[i].s2u_i);
684 
685 						ud[i].retry = 0;
686 						if (bytes < 0) {
687 #ifdef WIN32
688 							errno = WSAGetLastError();
689 #endif
690 							if (errno != EWOULDBLOCK) {
691 								perror("server_read");
692 								user_close(&ud[i]); /* inte data_close! */
693 							}
694 							continue;
695 						} else if ((bytes == 0) && ((&ud[i].s2u_buf[S2U_SIZE] - ud[i].s2u_i) > 0)){
696 							FD_CLR(ud[i].serv_fd,&wset);
697 							FD_CLR(ud[i].user_fd,&rset);
698 							user_close(&ud[i]);
699 							remove_this = 1;
700 						} else {
701 							if (bytes == (&ud[i].s2u_buf[S2U_SIZE] - ud[i].s2u_i)) {
702 								if (debug)
703 									printf("filled buffer - retrying\n");
704 								ud[i].retry = 1;
705 							}
706 							ud[i].s2u_i += bytes;
707 							FD_SET(ud[i].user_fd, &wset); /* Try to write this data below */
708 							if (debug) {
709 								printf("read %lu bytes from server control, trying to write later\n", (unsigned long)bytes);
710 								//printf("%s\n", (char*)(ud[i].s2u_i-bytes));
711 							}
712 						}
713 					}
714 				}
715 
716 				if (ud[i].data_connected == CONN_DATA_OK)  {
717 					if ((ud[i].retry_data && FD_ISSET(ud[i].user_data_fd,  &wset)) ||
718 					FD_ISSET(ud[i].serv_data_fd, &rset)) {
719 						if (ud[i].tls_status & TLS_DATA)
720 							bytes = tls_read(&ud[i], ud[i].ds2c_i,
721 							    &ud[i].ds2c_buf[DBUF_SIZE] - ud[i].ds2c_i, 1);
722 						else
723 							bytes = read(ud[i].serv_data_fd, ud[i].ds2c_i,
724 							    &ud[i].ds2c_buf[DBUF_SIZE] - ud[i].ds2c_i);
725 						ud[i].retry_data = 0;
726 						if (bytes < 0) {
727 #ifdef WIN32
728 							errno = WSAGetLastError();
729 #endif
730 							if (errno != EWOULDBLOCK) {
731 #ifdef WIN32
732 								printf("bytes = %u, err = %d\n", bytes, WSAGetLastError());
733 #endif
734 								perror("server_data_read1");
735 								data_close(&ud[i]);
736 							}
737 							continue;
738 						} else if ((bytes == 0) && ((&ud[i].ds2c_buf[DBUF_SIZE] - ud[i].ds2c_i) > 0) ){
739 								ud[i].serv_data_close = CLOSE_READ;
740 								if (debug)
741 									printf("setting CLOSE_READ in serv_data_close\n");
742 								if (ud[i].serv_read_cnt > 0) /* va? */
743 									ud[i].user_data_close = CLOSE_READ;
744 						} else {
745 							if (bytes == (&ud[i].ds2c_buf[DBUF_SIZE] - ud[i].ds2c_i)) {
746 								if (debug)
747 									printf("filled data buffer - retrying\n");
748 								ud[i].retry_data = 1;
749 							}
750 							if (debug)
751 								printf("read %ld bytes from serv_data_fd\n", (long)bytes);
752 							ud[i].ds2c_i += bytes;
753 							ud[i].serv_read_cnt += bytes;
754 							FD_SET(ud[i].user_data_fd, &wset); /* Try to write this data below */
755 						}
756 					}
757 
758 					if (FD_ISSET(ud[i].user_data_fd, &rset)) {
759 						bytes = read(ud[i].user_data_fd, ud[i].dc2s_i,
760 						    &ud[i].dc2s_buf[DBUF_SIZE] - ud[i].dc2s_i);
761 						if (bytes < 0) {
762 #ifdef WIN32
763 							errno = WSAGetLastError();
764 #endif
765 							if (errno != EWOULDBLOCK) {
766 #ifdef WIN32
767 								printf("bytes = %u, err = %d\n", bytes, WSAGetLastError());
768 #endif
769 								perror("server_data_read");
770 								data_close(&ud[i]);
771 							}
772 							continue;
773 						} else if (bytes == 0) {
774 								ud[i].user_data_close = CLOSE_READ;
775 								if (ud[i].user_read_cnt > 0)
776 									ud[i].serv_data_close = CLOSE_READ;
777 								if (debug)
778 									printf("setting CLOSE_READ in user_data_close\n");
779 						} else {
780 							if (debug)
781 								printf("read %ld bytes from user_data_fd\n", (long)bytes);
782 							ud[i].dc2s_i += bytes;
783 							ud[i].user_read_cnt += bytes;
784 							FD_SET(ud[i].serv_data_fd, &wset); /* Try to write this data below */
785 						}
786 					}
787 
788 				}
789 				if (ud[i].connected == CONN_YES && ud[i].data_connected == CONN_DATA_LISTEN) {
790 					if (debug)
791 						printf("conn_data_listen\n");
792 					if (FD_ISSET(ud[i].user_data_fd, &rset)) {
793 							if (debug)
794 								printf("trying to accept user data connection\n");
795 							if ( (newsock = accept(ud[i].user_data_fd, &sockaddr, &socklen)) != -1) {
796 								close(ud[i].user_data_fd);
797 								if (ud[i].active) {
798 									ud[i].user_data_fd = ud[i].serv_data_fd;
799 									ud[i].serv_data_fd = newsock;
800 									get_remote_ip(newsock, remoteip, sizeof(remoteip));
801 									strlcpy(ud[i].serv_data_host, remoteip, sizeof(ud[i].serv_data_host));
802 								} else
803 									ud[i].user_data_fd = newsock;
804 								ud[i].data_connected = CONN_DATA_OK;
805 								ud[i].ssl_data_fd_mode = TLS_NONE;
806 								ud[i].dc2s_i = ud[i].dc2s_o = ud[i].dc2s_buf;
807 								ud[i].ds2c_i = ud[i].ds2c_o = ud[i].ds2c_buf;
808 								ud[i].serv_data_close = CLOSE_NONE;
809 								ud[i].user_data_close = CLOSE_NONE;
810 								ud[i].user_read_cnt = 0;
811 								ud[i].serv_read_cnt = 0;
812 /*
813 								(void)setsockopt(ud[i].user_data_fd, SOL_SOCKET, SO_SNDLOWAT,
814 								    &tcpsndlowat, sizeof(tcpsndlowat));
815 								(void)setsockopt(ud[i].serv_data_fd, SOL_SOCKET, SO_SNDLOWAT,
816 								    &tcpsndlowat, sizeof(tcpsndlowat));
817 								(void)setsockopt(ud[i].user_data_fd, SOL_SOCKET, SO_SNDBUF,
818 								    &tcpbufsize, sizeof(tcpbufsize));
819 								(void)setsockopt(ud[i].serv_data_fd, SOL_SOCKET, SO_SNDBUF,
820 								    &tcpbufsize, sizeof(tcpbufsize));
821 								(void)setsockopt(ud[i].user_data_fd, SOL_SOCKET, SO_RCVBUF,
822 								    &tcpbufsize, sizeof(tcpbufsize));
823 								(void)setsockopt(ud[i].serv_data_fd, SOL_SOCKET, SO_RCVBUF,
824 								    &tcpbufsize, sizeof(tcpbufsize));
825 */
826 
827 								ud[i].data_connected = CONN_DATA_TLS;
828 								if (debug)
829 									printf("accept'ed client data connection\n");
830 								tls_auth(&ud[i], 1, ucertspath, cfg_cafile);
831 							} else
832 								printf("accept failed\n");
833 					}
834 				}
835 
836 				if (ud[i].user_fd != -1) {
837 					if (FD_ISSET(ud[i].user_fd,&rset)) {
838 						if ((bytes = read(ud[i].user_fd, ud[i].u2s_i, &ud[i].u2s_buf[U2S_SIZE]
839 						  - ud[i].u2s_i)) < 0) {
840 #ifdef WIN32
841 							errno = WSAGetLastError();
842 #endif
843 							if (errno != EWOULDBLOCK) {
844 								if (errno != ECONNRESET) {
845 									perror("user_read");
846 #ifdef WIN32
847 									printf("WSAGETLastError = %d\n", errno);
848 #endif
849 								}
850 								user_close(&ud[i]);
851 							}
852 						} else if (bytes==0) {
853 							user_close(&ud[i]);
854 						} else {
855 							ud[i].u2s_i += bytes;
856 							serv_write = 1;
857 						}
858 						if (ud[i].u2s_i - ud[i].u2s_o < 0)
859 							sys_err("bug1");
860 					}
861 				}
862 
863 				/* Write Section */
864 
865 				if (ud[i].data_connected == CONN_DATA_OK)  {
866 					if (FD_ISSET(ud[i].serv_data_fd, &wset) && ((bytes = ud[i].dc2s_i - ud[i].dc2s_o) > 0)) {
867 						if (ud[i].tls_status & TLS_DATA)
868 							bytesW = tls_write(&ud[i], ud[i].dc2s_o, bytes, 1);
869 						else
870 							bytesW = write(ud[i].serv_data_fd, ud[i].dc2s_o, bytes);
871 #ifdef WIN32
872 						errno = WSAGetLastError();
873 #endif
874 						if (bytesW < 0) {
875 							if (errno == EPIPE) {
876 								ud[i].serv_data_close = CLOSE_WRITE;
877 							}
878 							else if (errno != EWOULDBLOCK) {
879 								perror("serv_data_fd_write");
880 								data_close(&ud[i]);
881 							}
882 							continue;
883 						} else {
884 							if (debug)
885 								printf("wrote %ld bytes to serv_data_fd (of %ld requested)\n",
886 									(long)bytesW, (long)bytes);
887 							ud[i].dc2s_o += bytesW;
888 							if (ud[i].dc2s_o == ud[i].dc2s_i)
889 								ud[i].dc2s_o = ud[i].dc2s_i = ud[i].dc2s_buf;
890 						}
891 					}
892 
893 					if (FD_ISSET(ud[i].user_data_fd, &wset) && ((bytes = ud[i].ds2c_i - ud[i].ds2c_o) > 0)) {
894 						bytesW = write(ud[i].user_data_fd, ud[i].ds2c_o, bytes);
895 						if (bytesW < 0) {
896 #ifdef WIN32
897 							errno = WSAGetLastError();
898 #endif
899 							if (errno == EPIPE) {
900 								ud[i].user_data_close = CLOSE_WRITE;
901 							}
902 							if (errno != EWOULDBLOCK) {
903 								perror("user_data_fd_write");
904 								data_close(&ud[i]);
905 							}
906 							continue;
907 						} else {
908 							 if (debug)
909 								printf("wrote %ld bytes to user_data_fd (of %ld requested)\n",
910 								    (long)bytesW, (long)bytes);
911 							ud[i].ds2c_o += bytesW;
912 							if (ud[i].ds2c_o == ud[i].ds2c_i)
913 								ud[i].ds2c_o = ud[i].ds2c_i = ud[i].ds2c_buf;
914 						}
915 					}
916 
917 					if ( ( (ud[i].data_direction == DATA_DOWN && ud[i].serv_data_close == CLOSE_READ) ||
918 					     (ud[i].data_direction == DATA_UP && ud[i].user_data_close == CLOSE_READ) ||
919 					     (ud[i].serv_data_close == CLOSE_READ && ud[i].user_data_close == CLOSE_READ) ) &&
920 					     (ud[i].ds2c_o == ud[i].ds2c_i && ud[i].dc2s_o == ud[i].dc2s_i) )  {
921 						data_close(&ud[i]);
922 						if (debug)
923 							printf("data connection totally closed\n");
924 					}
925 /*
926 					if ( ud[i].ctrl_close ) &&
927 					     (ud[i].u2s_o == ud[i].u2s_i && ud[i].s2u_o == ud[i].s2u_i) )  {
928 						user_close(&ud[i]);
929 						if (debug)
930 							printf("user connection totally closed\n");
931 					}
932 */
933 				} /* ud[i].data_connected == CONN_DATA_OK */
934 
935 				/*
936 				if ((ud[i].connected == CONN_YES) || (ud[i].connected == CONN_IN_PROG)) {
937 					if (FD_ISSET(ud[i].serv_fd, &wset) && ((bytes = ud[i].u2s_i - ud[i].u2s_o) > 0))
938 						serv_write = 1;
939 				} else
940 				*/
941 				if ((bytes = ud[i].u2s_i - ud[i].u2s_o) > 0)
942 					serv_write = 1; /* OK? */
943 
944 				if (serv_write) {
945 					if (ud[i].connected != CONN_YES) {
946 						if ( (&ud[i].user_input[BUF_SIZE] - ud[i].user_ptr) >= bytes) {
947 							/* There is room in the user buffer for this data */
948 							memcpy(ud[i].user_ptr, ud[i].u2s_o, bytes);
949 							ud[i].u2s_o += bytes;
950 							ud[i].user_ptr += bytes;
951 							if (ud[i].u2s_o == ud[i].u2s_i)
952 								ud[i].u2s_o = ud[i].u2s_i = ud[i].u2s_buf;
953 						} else
954 							printf("could not copy user input to user buffer\n");
955 					} else {
956 						if (ud[i].prot == 'P') {
957 							intercept_user_buf(&ud[i], ud[i].u2s_o, &bytes);
958 							if (bytes == 0)
959 								ud[i].u2s_i = ud[i].u2s_o;
960 						}
961 						if (ud[i].tls_status & TLS_CTRL)
962 							bytesW = tls_write(&ud[i], ud[i].u2s_o, bytes, 0);
963 						else
964 							bytesW = write(ud[i].serv_fd, ud[i].u2s_o, bytes);
965 						if (bytesW < 0) {
966 #ifdef WIN32
967 							errno = WSAGetLastError();
968 #endif
969 							if (errno != EWOULDBLOCK) {
970 								perror("server_write");
971 								user_close(&ud[i]);
972 							}
973 							continue;
974 						} else {
975 							ud[i].u2s_o += bytesW;
976 							if (ud[i].u2s_o == ud[i].u2s_i)
977 								ud[i].u2s_o = ud[i].u2s_i = ud[i].u2s_buf;
978 						}
979 					}
980 				}
981 
982 				if ((bytes = ud[i].s2u_i - ud[i].s2u_o) > 0) {
983 					if (debug) {
984 						printf("there are %lu bytes to write", (unsigned long)bytes);
985 						if ((ud[i].serv_status == SERV_FLOW || ud[i].connected != CONN_YES ) && FD_ISSET(ud[i].user_fd,&wset) &&
986 						(memchr(ud[i].s2u_o, '\n', bytes) == NULL)) {
987 							printf(", but didn't write them because memchr!");
988 						}
989 						printf("\n");
990 					}
991 					if ((ud[i].serv_status == SERV_FLOW || ud[i].connected != CONN_YES ) && FD_ISSET(ud[i].user_fd,&wset) &&
992 						((memchr(ud[i].s2u_o, '\n', bytes) != NULL) || (ud[i].s2u_i == &ud[i].s2u_buf[S2U_SIZE]))
993 						) {
994 							if (debug)
995 								printf("calling change_serv_buf\n");
996 							if (change_serv_buf(&ud[i], ud[i].s2u_o)) {
997 								bytesW = bytes;
998 							} else
999 								bytesW = write(ud[i].user_fd, ud[i].s2u_o, bytes);
1000 
1001 						if (bytesW < 0) {
1002 #ifdef WIN32
1003 							errno = WSAGetLastError();
1004 #endif
1005 							if (errno != EWOULDBLOCK) {
1006 								perror("user_write");
1007 								user_close(&ud[i]);
1008 							}
1009 						} else {
1010 							ud[i].s2u_o+=bytesW;
1011 							if (debug) {
1012 								printf("wrote %lu bytes to user_fd\n", (unsigned long)bytesW);
1013 								//printf("%s\n", (char*)(ud[i].s2u_o-bytesW));
1014 							}
1015 							if (ud[i].s2u_o==ud[i].s2u_i)
1016 								ud[i].s2u_o = ud[i].s2u_i = ud[i].s2u_buf;
1017 						}
1018 					}  else if ( (ud[i].serv_status != SERV_FLOW) && (ud[i].connected==CONN_YES)) {
1019 						if ( (&ud[i].serv_input[BUF_SIZE] - ud[i].serv_ptr) >= bytes) {
1020 							/* There is room in the server buffer for this data */
1021 							if (debug)
1022 								printf("eating server bytes\n");
1023 							memcpy(ud[i].serv_ptr, ud[i].s2u_o, bytes);
1024 							ud[i].s2u_o += bytes;
1025 							ud[i].serv_ptr += bytes;
1026 							if (ud[i].s2u_o==ud[i].s2u_i)
1027 								ud[i].s2u_o = ud[i].s2u_i = ud[i].s2u_buf;
1028 						} else
1029 							printf("could not copy server input to server buffer\n");
1030 					}
1031 				}
1032 
1033 
1034 				/* Nonblocking connect to a remote data port gave a result */
1035 
1036 
1037 				if (ud[i].data_connected == CONN_IN_PROG && ud[i].connected == CONN_YES) {
1038 #if defined WIN32 || defined __CYGWIN__
1039 					if (FD_ISSET(ud[i].serv_data_fd,&eset) ||
1040 #else
1041 					if (FD_ISSET(ud[i].serv_data_fd,&rset) ||
1042 #endif
1043 						FD_ISSET(ud[i].serv_data_fd,&wset)) {
1044 						if (debug)
1045 							printf("nonblocking data connect\n");
1046 #if defined WIN32 || defined __CYGWIN__
1047 						conn_err = FD_ISSET(ud[i].serv_data_fd,&eset);
1048 #else
1049 						sock_errlen = sizeof(sock_err);
1050 						conn_err = 0;
1051 						if (getsockopt(ud[i].serv_data_fd, SOL_SOCKET, SO_ERROR, &sock_err,
1052 							&sock_errlen) < 0)
1053 							conn_err = 1; /* Solaris pending error */
1054 						else if (sock_err)
1055 							conn_err = 1; /* BSD pending error */
1056 						if (!conn_err) {
1057 							if (read(ud[i].serv_data_fd, fakebuf, 0) < 0)
1058 								conn_err = 1; /* We are not connected */
1059 						}
1060 #endif
1061 						if (debug)
1062 							printf("checking if %d is connected\n", ud[i].serv_data_fd);
1063 
1064 						if (conn_err) {
1065 							if (debug)
1066 								printf("data port connection failed\n");
1067 							print_to_ud(&ud[i],"421 Connection failed.\r\n");
1068 							data_close(&ud[i]);
1069 						} else {
1070 							ud[i].data_connected = CONN_YES;
1071 							if (debug)
1072 								printf("data port connected\n");
1073 							open_local_dataport(&ud[i]);
1074 						}
1075 
1076 					}
1077 				}
1078 
1079 				/* Nonblocking connect to remote server gave a result */
1080 
1081 				if (ud[i].connected == CONN_IN_PROG)
1082 #if defined WIN32 || defined __CYGWIN__
1083 					if (FD_ISSET(ud[i].serv_fd,&eset) ||
1084 #else
1085 					if (FD_ISSET(ud[i].serv_fd,&rset) ||
1086 #endif
1087 						FD_ISSET(ud[i].serv_fd,&wset)) {
1088 #if defined WIN32 || defined __CYGWIN__
1089 						conn_err = FD_ISSET(ud[i].serv_fd,&eset);
1090 #else
1091 						sock_errlen = sizeof(sock_err);
1092 						conn_err = 0;
1093 						if (getsockopt(ud[i].serv_fd, SOL_SOCKET, SO_ERROR, &sock_err,
1094 							&sock_errlen) < 0)
1095 							conn_err = 1; /* Solaris pending error */
1096 						else if (sock_err)
1097 							conn_err = 1; /* BSD pending error */
1098 
1099 						if (!conn_err) {
1100 							if (read(ud[i].serv_fd, fakebuf, 0) < 0)
1101 								conn_err = 1; /* We are not connected */
1102 						}
1103 #endif
1104 						if (conn_err) {
1105 							print_to_ud(&ud[i],"421 Connection failed.\r\n");
1106 							user_close(&ud[i]);
1107 							if (debug)
1108 								printf("failed connecting to server\n");
1109 						} else {
1110 							if (ud[i].issl) {
1111 							// Implicit SSL crap
1112 								ud[i].serv_status = SERV_TLS;
1113 								tls_auth(&ud[i], 0, ucertspath, cfg_cafile);
1114 							} else {
1115 								ud[i].serv_status = SERV_CONN;
1116 							}
1117 							ud[i].connected = CONN_YES;
1118 							if (debug)
1119 								printf("connected to server\n");
1120 						}
1121 					}
1122 			}
1123 			if (remove_this == 1)
1124 	      			ud[i].user_fd = -1;
1125 
1126 			else	{
1127 				if (ud[i].user_input != ud[i].user_ptr) {
1128 					/* if (debug)
1129 						printf("parse_buf\n"); */
1130 					while (parse_buf(&ud[i], i, dns_write_pipe, token) == 0);
1131 				}
1132 				if (ud[i].serv_input != ud[i].serv_ptr) {
1133 					/* if (debug)
1134 						printf("parse_serv_buf\n"); */
1135 					while (parse_serv_buf(&ud[i], i, ucertspath, cfg_cafile) == 0);
1136 				}
1137 			}
1138 		}
1139 	}
1140 }
1141 
1142