"Fossies" - the Fresh Open Source Software Archive 
Member "tlswrap-1.04/tlswrap.c" (29 Nov 2006, 34942 Bytes) of package /linux/privat/old/tlswrap-1.04.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "tlswrap.c" see the
Fossies "Dox" file reference documentation.
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, pipe1[2], pipe2[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
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)
134 DWORD service_execution_thread(LPDWORD param) {
135 return main2(serv_param.argc, serv_param.argv);
136 }
137 #endif
138
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(pipe1)) sys_err("pipe1");
274 if (pipe(pipe2)) sys_err("pipe2");
275
276 if ( (childpid = fork()) == 0) {
277 close(pipe1[1]);
278 close(pipe2[0]);
279 dns_helper(pipe1[0], pipe2[1]);
280 } else {
281 close(pipe1[0]);
282 close(pipe2[1]);
283 }
284
285 dns_write_pipe = pipe1[1];
286 dns_read_pipe = pipe2[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 pipe1[0] = setup_connect("127.0.0.1", port, &lport, &conn_res);
299 if (conn_res == 0) { /* connected OK */
300 if ((pipe1[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(pipe1[0], &wset)) {
307 if (FD_ISSET(temp_sock, &rset)) {
308 if ((pipe1[1] = accept(temp_sock, NULL, NULL)) == INVALID_SOCKET){
309 printf("setup error for fake pipe1: %d\n", WSAGetLastError());
310 exit(0);
311 }
312 } else sys_err("could not connect to local pipe 1");
313
314
315 pipe2[1] = setup_connect("127.0.0.1", port, &lport, &conn_res);
316 if (conn_res == 0) { /* connected OK */
317 if ((pipe2[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 ((pipe2[0] = accept(temp_sock, NULL, NULL)) == INVALID_SOCKET) {
325 printf("setup error for fake pipe2: %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 = pipe1[1];
334 dns_read_pipe = pipe2[0];
335
336 /* Turn off non-blocking for sockets to be used in the DNS helper */
337
338 sockarg = 0;
339
340 if (ioctlsocket(pipe1[0], FIONBIO, &sockarg) == SOCKET_ERROR) {
341 printf("ioctlsocket 1 failed because %d\n", WSAGetLastError());
342 exit(-1);
343 }
344
345 if (ioctlsocket(pipe2[1], FIONBIO, &sockarg) == SOCKET_ERROR) {
346 printf("ioctlsocket 2 failed because %d\n", WSAGetLastError());
347 exit(-1);
348 }
349 arg[0] = pipe1[0];
350 arg[1] = pipe2[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