1 /*
2  * Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #if 0
35 #ifndef lint
36 static char copyright[] =
37 "@(#) Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994\n\
38 	The Regents of the University of California.  All rights reserved.\n";
39 #endif /* not lint */
40 #endif
41 
42 #ifndef lint
43 #if 0
44 static char sccsid[] = "@(#)ftpd.c	8.4 (Berkeley) 4/16/94";
45 #endif
46 #endif /* not lint */
47 
48 #if 0
49 #include <sys/cdefs.h>
50 __FBSDID("$FreeBSD: src/libexec/ftpd/ftpd.c,v 1.201 2005/01/10 12:19:11 yar Exp $");
51 #endif
52 
53 /*
54  * FTP server.
55  */
56 #include <sys/param.h>
57 #include <sys/ioctl.h>
58 #include <sys/mman.h>
59 #include <sys/socket.h>
60 #include <sys/stat.h>
61 #include <sys/time.h>
62 #include <sys/wait.h>
63 
64 #include <netinet/in.h>
65 #include <netinet/in_systm.h>
66 #include <netinet/ip.h>
67 #include <netinet/tcp.h>
68 
69 #define	FTP_NAMES
70 #include <arpa/ftp.h>
71 #include <arpa/inet.h>
72 #include <arpa/telnet.h>
73 #include <ctype.h>
74 #include <dirent.h>
75 #include <err.h>
76 #include <errno.h>
77 #include <fcntl.h>
78 
79 #ifdef LINUX /* Linux port */
80 #include "bsdglob.h"
81 #else /* BSD source */
82 #include <glob.h>
83 #endif /* BSD source */
84 
85 #include <limits.h>
86 #include <netdb.h>
87 #include <pwd.h>
88 #include <grp.h>
89 #include <signal.h>
90 #include <stdint.h>
91 #include <stdio.h>
92 #include <stdlib.h>
93 #include <string.h>
94 #include <syslog.h>
95 #include <time.h>
96 
97 #ifdef LINUX /* Linux port */
98 #include <crypt.h> /* for crypt() instead of unistd.h ??? */
99 #ifdef USE_SENDFILE
100 #include <sys/sendfile.h>
101 #endif /* USE_SENDFILE */
102 #endif /* Linux port */
103 
104 #include <unistd.h>
105 #include <libutil.h>
106 
107 #ifdef HAVE_OPIE
108 #include <opie.h>
109 #endif
110 
111 #ifdef	LOGIN_CAP
112 #include <login_cap.h>
113 #endif
114 
115 #ifdef HAVE_SHADOW_H
116 #include <shadow.h>
117 #endif /* HAVE_SHADOW_H */
118 
119 #ifdef USE_PAM
120 #include <security/pam_appl.h>
121 #endif
122 
123 #ifdef TCPWRAPPERS
124 #include <tcpd.h>
125 #endif /* TCPWRAPPERS */
126 
127 #include "pathnames.h"
128 #include "extern.h"
129 
130 #include <stdarg.h>
131 
132 #include <port_base.h>
133 #include "ssl_port_ftpd.h"
134 
135 #ifdef USE_SSL
136 #include "sslapp.h"
137 
138 FILE	*cin, *cout;
139 char	ssl_file_path[MAXPATHLEN];
140 #endif /* USE_SSL */
141 
142 #ifdef	INTERNAL_LS
143 #ifdef USE_SSL
144 static char version[] = "Version 6.00LS+TLS";
145 #else /* !USE_SSL */
146 static char version[] = "Version 6.00LS";
147 #endif /* USE_SSL */
148 #undef main
149 #else
150 #ifdef USE_SSL
151 static char version[] = "Version 6.00+TLS";
152 #else /* !USE_SSL */
153 static char version[] = "Version 6.00";
154 #endif /* USE_SSL */
155 #endif
156 
157 extern	off_t restart_point;
158 extern	char cbuf[];
159 
160 union sockunion ctrl_addr;
161 union sockunion data_source;
162 union sockunion data_dest;
163 union sockunion his_addr;
164 union sockunion pasv_addr;
165 
166 int	daemon_mode;
167 int	data;
168 int	dataport;
169 int	hostinfo = 1;	/* print host-specific info in messages */
170 int	logged_in;
171 struct	passwd *pw;
172 char	*homedir;
173 int	ftpdebug;
174 int	timeout = 900;    /* timeout after 15 minutes of inactivity */
175 int	maxtimeout = 7200;/* don't allow idle time to be set beyond 2 hours */
176 int	logging;
177 int	restricted_data_ports = 1;
178 int	ftpdparanoid = 1; /* be extra careful about security */
179 int	anon_only = 0;    /* Only anonymous ftp allowed */
180 int	guest;
181 int	dochroot;
182 char	*chrootdir;
183 char	rchrootdir[MAXPATHLEN + 1];
184 int	dowtmp = 1;
185 int	stats;
186 int	statfd = -1;
187 int	type;
188 int	form;
189 int	stru;			/* avoid C keyword */
190 int	mode;
191 int	usedefault = 1;		/* for data transfers */
192 int	pdata = -1;		/* for passive mode */
193 int	readonly = 0;		/* Server is in readonly mode.	*/
194 int	noepsv = 0;		/* EPSV command is disabled.	*/
195 int	noretr = 0;		/* RETR command is disabled.	*/
196 int	noguestretr = 0;	/* RETR command is disabled for anon users. */
197 int	noguestmkd = 0;		/* MKD command is disabled for anon users. */
198 int	noguestmod = 1;		/* anon users may not modify existing files. */
199 
200 static volatile sig_atomic_t recvurg = 0;
201 static volatile sig_atomic_t recvlostconn = 0;
202 sig_atomic_t transflag;
203 off_t	file_size;
204 off_t	byte_count;
205 #if !defined(CMASK) || CMASK == 0
206 #undef CMASK
207 #define CMASK 022
208 #endif
209 int	defumask = CMASK;		/* default umask value */
210 char	tmpline[7];
211 char	*hostname;
212 int	epsvall = 0;
213 
214 #ifdef VIRTUAL_HOSTING
215 char	*ftpuser;
216 
217 static struct ftphost {
218 	struct ftphost	*next;
219 	struct addrinfo *hostinfo;
220 	char		*hostname;
221 	char		*anonuser;
222 	char		*statfile;
223 	char		*welcome;
224 	char		*loginmsg;
225 	char		*anondir;
226 } *thishost, *firsthost;
227 
228 #endif
229 char	remotehost[NI_MAXHOST];
230 char	*ident = NULL;
231 
232 static char	ttyline[20];
233 char		*tty = ttyline;		/* for klogin */
234 
235 #ifdef USE_PAM
236 static int	auth_pam(struct passwd**, const char*);
237 pam_handle_t	*pamh = NULL;
238 static void	ftpd_openlog();
239 #endif
240 
241 #ifdef HAVE_OPIE
242 static struct	opie opiedata;
243 static char	opieprompt[OPIE_CHALLENGE_MAX+1];
244 static int	pwok;
245 #endif
246 
247 #ifdef TCPWRAPPERS
248 static int	check_host(struct sockaddr *);
249 int		allow_severity = LOG_INFO;
250 int		deny_severity = LOG_NOTICE;
251 #endif /* TCPWRAPPERS */
252 
253 /*
254  * wu-ftpd style xferlog
255  */
256 #define XFERLOG_ORIG	1 /* use original format */
257 #define XFERLOG_EXT	2 /* use extended format */
258 int	xferlog_stat = 0; /* xferlog format for stat file */
259 int	xferlog_syslog = 0; /* xferlog format for syslog */
260 /*
261  * Options for xferlog
262  */
263 /* Use pathnames relative to the real root dir: */
264 int	xferlog_wu_realroot = 0;   /* for wu-orig/wu-ext formats */
265 int	xferlog_anon_realroot = 0; /* for the "anon" format */
266 
267 char	*pid_file = NULL;
268 
269 /*
270  * Override the IP address that will be advertised to IPv4 clients in response
271  * to the PASV/LPSV commands.
272  */
273 int		tun_pasvip_flag = 0;
274 union		sockunion tun_pasvip_addr;
275 static int	set_pasvip_addr();
276 
277 /*
278  * Define the service name
279  */
280 #define _SERVICE_NAME "ftpd"
281 
282 /*
283  * Limit number of pathnames that glob can return.
284  * A limit of 0 indicates the number of pathnames is unlimited.
285  */
286 #define MAXGLOBARGS	16384
287 
288 /*
289  * Timeout intervals for retrying connections
290  * to hosts that don't accept PORT cmds.  This
291  * is a kludge, but given the problems with TCP...
292  */
293 #define	SWAITMAX	90	/* wait at most 90 seconds */
294 #define	SWAITINT	5	/* interval between retries */
295 
296 int	swaitmax = SWAITMAX;
297 int	swaitint = SWAITINT;
298 
299 #ifdef SETPROCTITLE
300 #ifdef OLD_SETPROCTITLE
301 char	**Argv = NULL;		/* pointer to argument vector */
302 char	*LastArgv = NULL;	/* end of argv */
303 #endif /* OLD_SETPROCTITLE */
304 char	proctitle[LINE_MAX];	/* initial part of title */
305 #endif /* SETPROCTITLE */
306 
307 #define LOGCMD(cmd, file)		logcmd((cmd), (file), NULL, -1)
308 #define LOGCMD2(cmd, file1, file2)	logcmd((cmd), (file1), (file2), -1)
309 #define LOGBYTES(cmd, file, cnt)	logcmd((cmd), (file), NULL, (cnt))
310 
311 #ifdef VIRTUAL_HOSTING
312 static void	 inithosts(void);
313 static void	 selecthost(union sockunion *);
314 #endif
315 static void	 ack(char *);
316 static void	 sigurg(int);
317 static int	 myoob(void);
318 static int	 checkuser(char *, char *, int, char **);
319 static FILE	*dataconn(char *, off_t, char *);
320 static void	 dolog(struct sockaddr *);
321 static void	 end_login(void);
322 static FILE	*getdatasock(char *);
323 static int	 guniquefd(char *, char **);
324 static void	 lostconn(int);
325 static void	 sigquit(int);
326 static int	 receive_data(FILE *, FILE *);
327 static int	 send_data(FILE *, FILE *, size_t, off_t, int);
328 static struct passwd *
329 		 sgetpwnam(char *);
330 static char	*sgetsave(char *);
331 static void	 reapchild(int);
332 static void	 appendf(char **, char *, ...);
333 static void	 logcmd(char *, char *, char *, off_t);
334 static void	 logxfer(char *, char *, off_t, time_t, time_t, int, int);
335 static void	 logxfer_anon(char *, off_t, time_t, time_t);
336 static void	 logxfer_wuftpd(char *, char *, off_t, time_t, time_t, int, int);
337 static char	*doublequote(char *);
338 static int	*socksetup(int, char *, const char *);
339 
340 int
main(int argc,char * argv[],char ** envp)341 main(int argc, char *argv[], char **envp)
342 {
343 	int addrlen, ch, on = 1, tos;
344 	char *cp, line[LINE_MAX];
345 	FILE *fd;
346 	char	*bindname = NULL;
347 	const char *bindport = "ftp";
348 #ifdef INET6
349 	int	family = AF_UNSPEC;
350 #else /* !INET6 */
351 	int	family = AF_INET;
352 #endif /* INET6 */
353 	struct sigaction sa;
354 	char *tun_pasvip_str = NULL;
355 
356 	tzset();		/* in case no timezone database in ~ftp */
357 	sigemptyset(&sa.sa_mask);
358 	sa.sa_flags = SA_RESTART;
359 
360 #ifdef OLD_SETPROCTITLE
361 	/*
362 	 *  Save start and extent of argv for setproctitle.
363 	 */
364 	Argv = argv;
365 	while (*envp)
366 		envp++;
367 	LastArgv = envp[-1] + strlen(envp[-1]);
368 #endif /* OLD_SETPROCTITLE */
369 
370 	/*
371 	 * Prevent diagnostic messages from appearing on stderr.
372 	 * We run as a daemon or from inetd; in both cases, there's
373 	 * more reason in logging to syslog.
374 	 */
375 	(void) freopen(_PATH_DEVNULL, "w", stderr);
376 	opterr = 0;
377 
378 #ifdef USE_PAM
379 	ftpd_openlog();
380 #else /* Original code */
381 	/*
382 	 * LOG_NDELAY sets up the logging connection immediately,
383 	 * necessary for anonymous ftp's that chroot and can't do it later.
384 	 */
385 	openlog(_SERVICE_NAME, LOG_PID | LOG_NDELAY, LOG_FTP);
386 #endif /* USE_PAM */
387 
388 	while ((ch = getopt(argc, argv,
389 	                    "46a:AdDEhlL:mMoOp:P:rRS:t:T:u:UvWX:z:")) != -1) {
390 		switch (ch) {
391 			char *optname;
392 			size_t optnamelen;
393 		case '4':
394 			family = (family == AF_INET6) ? AF_UNSPEC : AF_INET;
395 			break;
396 
397 #ifdef INET6
398 		case '6':
399 			family = (family == AF_INET) ? AF_UNSPEC : AF_INET6;
400 			break;
401 #endif
402 
403 		case 'a':
404 			optname = "bind=";
405 			optnamelen = strlen(optname);
406 			if (strncmp(optarg, optname, optnamelen) == 0) {
407 			    bindname = optarg + optnamelen;
408 			    break;
409 			}
410 			optname = "pasvip=";
411 			optnamelen = strlen(optname);
412 			if (strncmp(optarg, optname, optnamelen) == 0) {
413 			    tun_pasvip_str = optarg + optnamelen;
414 			    tun_pasvip_flag = 1;
415 			    break;
416 			}
417 			syslog(LOG_WARNING, "bad value for -a");
418 			break;
419 
420 		case 'A':
421 			anon_only = 1;
422 			break;
423 
424 		case 'd':
425 			ftpdebug++;
426 			break;
427 
428 		case 'D':
429 			daemon_mode++;
430 			break;
431 
432 		case 'E':
433 			noepsv = 1;
434 			break;
435 
436 		case 'h':
437 			hostinfo = 0;
438 			break;
439 
440 		case 'l':
441 			logging++;	/* > 1 == extra logging */
442 			break;
443 
444 		case 'L':
445 			if (strcmp(optarg, "anon-abs") == 0) {
446 			    xferlog_anon_realroot = 1;
447 			    break;
448 			}
449 			if (strcmp(optarg, "wu-abs") == 0) {
450 			    xferlog_wu_realroot = 1;
451 			    break;
452 			}
453 			syslog(LOG_WARNING, "bad value for -L");
454 			break;
455 
456 		case 'm':
457 			noguestmod = 0;
458 			break;
459 
460 		case 'M':
461 			noguestmkd = 1;
462 			break;
463 
464 		case 'o':
465 			noretr = 1;
466 			break;
467 
468 		case 'O':
469 			noguestretr = 1;
470 			break;
471 
472 		case 'p':
473 			pid_file = optarg;
474 			break;
475 
476 		case 'P':
477 			bindport = optarg;
478 			break;
479 
480 		case 'r':
481 			readonly = 1;
482 			break;
483 
484 		case 'R':
485 			ftpdparanoid = 0;
486 			break;
487 
488 		case 'S':
489 			if (strcmp(optarg, "anon") == 0) {
490 			    stats = 1;
491 			    break;
492 			}
493 			if (strcmp(optarg, "wu-orig") == 0) {
494 			    xferlog_stat = XFERLOG_ORIG;
495 			    break;
496 			}
497 			if (strcmp(optarg, "wu-ext") == 0) {
498 			    xferlog_stat = XFERLOG_EXT;
499 			    break;
500 			}
501 			syslog(LOG_WARNING, "bad value for -S");
502 			break;
503 
504 		case 't':
505 			timeout = atoi(optarg);
506 			if (maxtimeout < timeout)
507 				maxtimeout = timeout;
508 			break;
509 
510 		case 'T':
511 			maxtimeout = atoi(optarg);
512 			if (timeout > maxtimeout)
513 				timeout = maxtimeout;
514 			break;
515 
516 		case 'u':
517 		    {
518 			long val = 0;
519 
520 			val = strtol(optarg, &optarg, 8);
521 			if (*optarg != '\0' || val < 0)
522 				syslog(LOG_WARNING, "bad value for -u");
523 			else
524 				defumask = val;
525 			break;
526 		    }
527 		case 'U':
528 			restricted_data_ports = 0;
529 			break;
530 
531 		case 'v':
532 			ftpdebug++;
533 			break;
534 
535 		case 'W':
536 			dowtmp = 0;
537 			break;
538 
539 		case 'X':
540 			if (strcmp(optarg, "wu-orig") == 0) {
541 			    xferlog_syslog = XFERLOG_ORIG;
542 			    break;
543 			}
544 			if (strcmp(optarg, "wu-ext") == 0) {
545 			    xferlog_syslog = XFERLOG_EXT;
546 			    break;
547 			}
548 			syslog(LOG_WARNING, "bad value for -X");
549 			break;
550 
551 #ifdef USE_SSL
552 		case 'z':
553 			if ( (strcmp(optarg, "tls") == 0) ||
554 			     (strcmp(optarg, "nossl") == 0) ) {
555 			    SSL_secure_flags_ON(SSL_USE_TLS);
556 			    SSL_secure_flags_OFF(SSL_USE_COMPAT);
557 			}
558 			if ( (strcmp(optarg, "ssl") == 0) ||
559 			     (strcmp(optarg, "notls") == 0) ) {
560 			    SSL_secure_flags_ON(SSL_USE_COMPAT);
561 			    SSL_secure_flags_OFF(SSL_USE_TLS);
562 			}
563 			if (strcmp(optarg, "secure") == 0) {
564 			    SSL_secure_flags_ON(SSL_ENABLED);
565 			    SSL_secure_flags_OFF(SSL_USE_NONSECURE);
566 			}
567 			/* disable *all* ssl stuff */
568 			if (strcmp(optarg, "nosecure") == 0) {
569 			    SSL_secure_flags_ON(SSL_USE_NONSECURE);
570 			    SSL_secure_flags_OFF(SSL_ENABLED);
571 			}
572 			if (strcmp(optarg, "refnu") == 0) {
573 			    ssl_rpnu_flag = 1;
574 			}
575 			if (strcmp(optarg, "defau") == 0) {
576 			    ssl_dpau_flag = 1;
577 			}
578 			optname = "verify=";
579 			optnamelen = strlen(optname);
580 			if (strncmp(optarg, optname, optnamelen) == 0) {
581 		    	    switch (atoi(optarg + optnamelen)) {
582 			    case 0:
583 				ssl_verify_flag = SSL_VERIFY_NONE;
584 				break;
585 			    case 1:
586 				ssl_verify_flag = SSL_VERIFY_PEER;
587 				break;
588 			    case 2:
589 				ssl_verify_flag = SSL_VERIFY_PEER |
590 				    SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
591 				break;
592 			    default:
593 				syslog(LOG_WARNING,
594 				    "unknown verify level ignored: %d",
595 				    atoi(optarg + optnamelen));
596 			    }
597 			}
598 			optname = "cert=";
599 			optnamelen = strlen(optname);
600 			if (strncmp(optarg, optname, optnamelen) == 0) {
601 			    ssl_cert_file = optarg + optnamelen;
602 			}
603 			optname = "key=";
604 			optnamelen = strlen(optname);
605 			if (strncmp(optarg, optname, optnamelen) == 0) {
606 			    ssl_key_file = optarg + optnamelen;
607 			}
608 			optname = "logfile=";
609 			optnamelen = strlen(optname);
610 			if (strncmp(optarg, optname, optnamelen) == 0) {
611 			    ssl_log_file = optarg + optnamelen;
612 			}
613 			if (strcmp(optarg, "debug") == 0 ) {
614 			    ssl_debug_flag = 1;
615 			}
616 			optname = "cipher=";
617 			optnamelen = strlen(optname);
618 			if (strncmp(optarg, optname, optnamelen) == 0) {
619 			    ssl_cipher_list = optarg + optnamelen;
620 			}
621 			optname = "CAfile=";
622 			optnamelen = strlen(optname);
623 			if (strncmp(optarg, optname, optnamelen) == 0) {
624 			    ssl_CA_file = optarg + optnamelen;
625 			}
626 			optname = "CApath=";
627 			optnamelen = strlen(optname);
628 			if (strncmp(optarg, optname, optnamelen) == 0) {
629 			    ssl_CA_path = optarg + optnamelen;
630 			}
631 			optname = "CRLfile=";
632 			optnamelen = strlen(optname);
633 			if (strncmp(optarg, optname, optnamelen) == 0) {
634 			    ssl_CRL_file = optarg + optnamelen;
635 			}
636 			optname = "CRLpath=";
637 			optnamelen = strlen(optname);
638 			if (strncmp(optarg, optname, optnamelen) == 0) {
639 			    ssl_CRL_path = optarg + optnamelen;
640 			}
641 			if (strcmp(optarg, "apbu") == 0) {
642 			    ssl_apbu_flag = 1;
643 			}
644 			if (strcmp(optarg, "uorc") == 0) {
645 			    ssl_uorc_flag = 1;
646 			}
647 			optname = "auth=";
648 			optnamelen = strlen(optname);
649 			if (strncmp(optarg, optname, optnamelen) == 0) {
650 		    	    switch (atoi(optarg + optnamelen)) {
651 			    case 0:
652 				x509_auth_flag = X509_AUTH_DISABLED;
653 				break;
654 			    case 1:
655 				x509_auth_flag = X509_AUTH_SUFFICIENT;
656 				break;
657 			    case 2:
658 				x509_auth_flag = X509_AUTH_REQUIRED;
659 				break;
660 			    case 3:
661 				x509_auth_flag = X509_AND_STANDARD_AUTH;
662 				break;
663 			    default:
664 				syslog(LOG_WARNING,
665 				    "unknown X.509 auth level ignored: %d",
666 				    atoi(optarg + optnamelen));
667 			    }
668 			}
669 			if (strcmp(optarg, "verbose") == 0) {
670 			    ssl_verbose_flag = 1;
671 			}
672 			break;
673 #endif /* USE_SSL */
674 
675 		default:
676 			syslog(LOG_WARNING, "unknown flag -%c ignored", optopt);
677 			break;
678 		}
679 	}
680 
681 	/* check option dependencies */
682 #ifdef USE_SSL
683 	if ((ssl_log_file == NULL) && ssl_debug_flag) {
684 		syslog(LOG_WARNING, "no TLS/SSL log file specified");
685 		exit(1);
686 	}
687 #endif /* USE_SSL */
688 
689 #ifdef USE_SSL
690 	/*
691 	 * Make sure we have access to the required certificate and key files
692 	 * before we chroot and do the other "muck" for anon-ftp style setup...
693 	 */
694 	/*
695 	 * Keep the macros that are common between the client and the server
696 	 * happy.
697 	 */
698 	cin = stdin;
699 	cout = stderr;
700 
701 	/* Do things the "default" way. */
702 	ssl_logerr_syslog = 1;
703 	if (ssl_cert_file == NULL) {
704 		snprintf(ssl_file_path, sizeof(ssl_file_path), "%s/%s",
705 		    X509_get_default_cert_dir(), "ftpd.pem");
706 		ssl_cert_file = ssl_file_path;
707 	}
708 
709 	if (!do_ssleay_init(1)) {
710 		syslog(LOG_ERR, "TLS/SSL initialization failed");
711 		exit(1);
712 	}
713 #endif /* USE_SSL */
714 
715 #ifdef VIRTUAL_HOSTING
716 	inithosts();
717 #endif
718 
719 	if (daemon_mode) {
720 		int *ctl_sock, fd, maxfd = -1, nfds, i;
721 		fd_set defreadfds, readfds;
722 		pid_t pid;
723 
724 		/* Set the IP address for passive mode. */
725 		if (tun_pasvip_flag) {
726 			if (!set_pasvip_addr(tun_pasvip_str))
727 				exit(1);
728 		}
729 
730 		/*
731 		 * Detach from parent.
732 		 */
733 		if (daemon(1, 1) < 0) {
734 			syslog(LOG_ERR, "failed to become a daemon");
735 			exit(1);
736 		}
737 		sa.sa_handler = reapchild;
738 		(void)sigaction(SIGCHLD, &sa, NULL);
739 
740 		/*
741 		 * Open a socket, bind it to the FTP port, and start
742 		 * listening.
743 		 */
744 		ctl_sock = socksetup(family, bindname, bindport);
745 		if (ctl_sock == NULL)
746 			exit(1);
747 
748 		FD_ZERO(&defreadfds);
749 		for (i = 1; i <= *ctl_sock; i++) {
750 			FD_SET(ctl_sock[i], &defreadfds);
751 			if (listen(ctl_sock[i], 32) < 0) {
752 				syslog(LOG_ERR, "control listen: %m");
753 				exit(1);
754 			}
755 			if (maxfd < ctl_sock[i])
756 				maxfd = ctl_sock[i];
757 		}
758 
759 		/*
760 		 * Atomically write process ID
761 		 */
762 		if (pid_file)
763 		{
764 			int fd;
765 			char buf[20];
766 
767 			fd = open(pid_file, O_CREAT | O_WRONLY | O_TRUNC
768 				| O_NONBLOCK
769 #ifndef LINUX /* BSD source */
770 				| O_EXLOCK
771 #endif /* BSD source */
772 				, 0644);
773 			if (fd < 0) {
774 				if (errno == EAGAIN)
775 					syslog(LOG_ERR,
776 					    "%s: already locked", pid_file);
777 				else
778 					syslog(LOG_ERR, "%s: %m", pid_file);
779 				exit(1);
780 			}
781 			snprintf(buf, sizeof(buf),
782 				"%lu\n", (unsigned long) getpid());
783 			if (write(fd, buf, strlen(buf)) < 0) {
784 				syslog(LOG_ERR, "%s: write: %m", pid_file);
785 				exit(1);
786 			}
787 			/* Leave the pid file open and locked */
788 		}
789 		/*
790 		 * Loop forever accepting connection requests and forking off
791 		 * children to handle them.
792 		 */
793 		while (1) {
794 			FD_COPY(&defreadfds, &readfds);
795 			nfds = select(maxfd + 1, &readfds, NULL, NULL, 0);
796 			if (nfds <= 0) {
797 				if (nfds < 0 && errno != EINTR)
798 					syslog(LOG_WARNING, "select: %m");
799 				continue;
800 			}
801 
802 			pid = -1;
803                         for (i = 1; i <= *ctl_sock; i++)
804 				if (FD_ISSET(ctl_sock[i], &readfds)) {
805 					addrlen = sizeof(his_addr);
806 					fd = accept(ctl_sock[i],
807 					    (struct sockaddr *)&his_addr,
808 					    &addrlen);
809 					if (fd >= 0) {
810 						if ((pid = fork()) == 0) {
811 							/* child */
812 							(void) dup2(fd, 0);
813 							(void) dup2(fd, 1);
814 							close(ctl_sock[i]);
815 						} else
816 							close(fd);
817 					}
818 				}
819 			if (pid == 0)
820 				break;
821 		}
822 	} else {
823 		addrlen = sizeof(his_addr);
824 		if (getpeername(0, (struct sockaddr *)&his_addr, &addrlen) < 0) {
825 			syslog(LOG_ERR, "getpeername (%s): %m",argv[0]);
826 			exit(1);
827 		}
828 	}
829 
830 	sa.sa_handler = SIG_DFL;
831 	(void)sigaction(SIGCHLD, &sa, NULL);
832 
833 	sa.sa_handler = sigurg;
834 	sa.sa_flags = SA_RESTART;	/* default BSD style */
835 	(void)sigaction(SIGURG, &sa, NULL);
836 #ifdef USE_SSL /* "pseudo-OOB" with SSL */
837 	(void)sigaction(SIGIO, &sa, NULL);
838 #endif /*USE_SSL*/
839 
840 	sigfillset(&sa.sa_mask);	/* block all signals in handler */
841 	sa.sa_flags = SA_RESTART;
842 	sa.sa_handler = sigquit;
843 	(void)sigaction(SIGHUP, &sa, NULL);
844 	(void)sigaction(SIGINT, &sa, NULL);
845 	(void)sigaction(SIGQUIT, &sa, NULL);
846 	(void)sigaction(SIGTERM, &sa, NULL);
847 
848 	sa.sa_handler = lostconn;
849 	(void)sigaction(SIGPIPE, &sa, NULL);
850 
851 	addrlen = sizeof(ctrl_addr);
852 	if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) {
853 		syslog(LOG_ERR, "getsockname (%s): %m",argv[0]);
854 		exit(1);
855 	}
856 	dataport = ntohs(ctrl_addr.su_port) - 1; /* as per RFC 959 */
857 #ifdef VIRTUAL_HOSTING
858 	/* select our identity from virtual host table */
859 	selecthost(&ctrl_addr);
860 #endif
861 #ifdef IP_TOS
862 	if (ctrl_addr.su_family == AF_INET)
863       {
864 	tos = IPTOS_LOWDELAY;
865 	if (setsockopt(0, IPPROTO_IP, IP_TOS, &tos, sizeof(int)) < 0)
866 		syslog(LOG_WARNING, "control setsockopt (IP_TOS): %m");
867       }
868 #endif
869 	/*
870 	 * Disable Nagle on the control channel so that we don't have to wait
871 	 * for peer's ACK before issuing our next reply.
872 	 */
873 	if (setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
874 		syslog(LOG_WARNING, "control setsockopt (TCP_NODELAY): %m");
875 
876 	data_source.su_port = htons(ntohs(ctrl_addr.su_port) - 1);
877 
878 	/* set this here so klogin can use it... */
879 	(void)snprintf(ttyline, sizeof(ttyline), "ftp%d", getpid());
880 
881 	/* Try to handle urgent data inline */
882 #ifdef SO_OOBINLINE
883 	if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on)) < 0)
884 		syslog(LOG_WARNING, "control setsockopt (SO_OOBINLINE): %m");
885 #endif
886 
887 #ifdef	F_SETOWN
888 	if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1)
889 		syslog(LOG_ERR, "fcntl F_SETOWN: %m");
890 #endif
891 #ifdef	USE_SSL /* "pseudo-OOB" with SSL */
892 	if (fcntl(fileno(stdin), F_SETFL, O_ASYNC) == -1)
893 		syslog(LOG_ERR, "fcntl F_SETFL: %m");
894 #endif /*USE_SSL*/
895 
896 	dolog((struct sockaddr *)&his_addr);
897 #ifdef TCPWRAPPERS
898 	/* If ftpd runs in the daemon mode, this code is reachable only in the
899 	 * child process. */
900 	if (daemon_mode) {
901 		/* Use tcp_wrappers to filter incoming requests. */
902 		if (!check_host((struct sockaddr *)&his_addr))
903 			dologout(0);
904 	}
905 #endif /* TCPWRAPPERS */
906 
907 	/* Set the IP address for passive mode. */
908 	if (tun_pasvip_flag && !daemon_mode) {
909 		if (!set_pasvip_addr(tun_pasvip_str)) {
910 			fatalerror("Can't set an IP address for passive mode");
911 		}
912 	}
913 
914 	/*
915 	 * Set up default state
916 	 */
917 	data = -1;
918 	type = TYPE_A;
919 	form = FORM_N;
920 	stru = STRU_F;
921 	mode = MODE_S;
922 	tmpline[0] = '\0';
923 
924 	/* If logins are disabled, print out the message. */
925 	if ((fd = fopen(_PATH_NOLOGIN,"r")) != NULL) {
926 		while (fgets(line, sizeof(line), fd) != NULL) {
927 			if ((cp = strchr(line, '\n')) != NULL)
928 				*cp = '\0';
929 			lreply(530, "%s", line);
930 		}
931 		(void) FFLUSH(stdout);
932 		(void) fclose(fd);
933 		reply(530, "System not available.");
934 		if (logging)
935 			syslog(LOG_INFO, "logins are disallowed systemwide");
936 		dologout(0);
937 	}
938 #ifdef VIRTUAL_HOSTING
939 	fd = fopen(thishost->welcome, "r");
940 #else
941 	fd = fopen(_PATH_FTPWELCOME, "r");
942 #endif
943 	if (fd != NULL) {
944 		while (fgets(line, sizeof(line), fd) != NULL) {
945 			if ((cp = strchr(line, '\n')) != NULL)
946 				*cp = '\0';
947 			lreply(220, "%s", line);
948 		}
949 		(void) FFLUSH(stdout);
950 		(void) fclose(fd);
951 		/* reply(220,) must follow */
952 	}
953 #ifndef VIRTUAL_HOSTING
954 	if ((hostname = malloc(MAXHOSTNAMELEN)) == NULL)
955 		fatalerror("Ran out of memory.");
956 	if (gethostname(hostname, MAXHOSTNAMELEN - 1) < 0)
957 		hostname[0] = '\0';
958 	hostname[MAXHOSTNAMELEN - 1] = '\0';
959 #endif
960 	if (hostinfo)
961 		reply(220, "%s FTP server (%s) ready.", hostname, version);
962 	else
963 		reply(220, "FTP server ready.");
964 	for (;;)
965 		(void) yyparse();
966 	/* NOTREACHED */
967 }
968 
969 static void
lostconn(int signo)970 lostconn(int signo)
971 {
972 
973 	recvlostconn = 1;
974 	dologout(1);
975 }
976 
977 static void
sigquit(int signo)978 sigquit(int signo)
979 {
980 
981 	syslog(LOG_ERR, "got signal %d", signo);
982 	dologout(1);
983 }
984 
985 #ifdef VIRTUAL_HOSTING
986 /*
987  * read in virtual host tables (if they exist)
988  */
989 
990 static void
inithosts(void)991 inithosts(void)
992 {
993 	int insert;
994 	size_t len;
995 	FILE *fp;
996 	char *cp, *mp, *line;
997 	char *hostname;
998 	char *vhost, *anonuser, *statfile, *welcome, *loginmsg, *anondir;
999 	struct ftphost *hrp, *lhrp;
1000 	struct addrinfo hints, *res, *ai;
1001 
1002 	/*
1003 	 * Fill in the default host information
1004 	 */
1005 	if ((hostname = malloc(MAXHOSTNAMELEN)) == NULL)
1006 		fatalerror("Ran out of memory.");
1007 	if (gethostname(hostname, MAXHOSTNAMELEN - 1) < 0)
1008 		hostname[0] = '\0';
1009 	hostname[MAXHOSTNAMELEN - 1] = '\0';
1010 	if ((hrp = malloc(sizeof(struct ftphost))) == NULL)
1011 		fatalerror("Ran out of memory.");
1012 	hrp->hostname = hostname;
1013 	hrp->hostinfo = NULL;
1014 
1015 	memset(&hints, 0, sizeof(hints));
1016 	hints.ai_flags = AI_CANONNAME;
1017 	hints.ai_family = AF_UNSPEC;
1018 	if (getaddrinfo(hrp->hostname, NULL, &hints, &res) == 0)
1019 		hrp->hostinfo = res;
1020 	hrp->statfile = _PATH_FTPDSTATFILE;
1021 	hrp->welcome  = _PATH_FTPWELCOME;
1022 	hrp->loginmsg = _PATH_FTPLOGINMESG;
1023 	hrp->anonuser = "ftp";
1024 	hrp->anondir  = NULL;
1025 	hrp->next = NULL;
1026 	thishost = firsthost = lhrp = hrp;
1027 	if ((fp = fopen(_PATH_FTPHOSTS, "r")) != NULL) {
1028 		int gothost;
1029 
1030 		while ((line = fgetln(fp, &len)) != NULL) {
1031 			int	i;
1032 
1033 			/* skip comments */
1034 			if (line[0] == '#')
1035 				continue;
1036 			if (line[len - 1] == '\n') {
1037 				line[len - 1] = '\0';
1038 				mp = NULL;
1039 			} else {
1040 				if ((mp = malloc(len + 1)) == NULL)
1041 					fatalerror("Ran out of memory.");
1042 				memcpy(mp, line, len);
1043 				mp[len] = '\0';
1044 				line = mp;
1045 			}
1046 			cp = strtok(line, " \t");
1047 			/* skip empty lines */
1048 			if (cp == NULL)
1049 				goto nextline;
1050 			vhost = cp;
1051 
1052 			/* set defaults */
1053 			anonuser = "ftp";
1054 			anondir  = NULL;
1055 			statfile = _PATH_FTPDSTATFILE;
1056 			welcome  = _PATH_FTPWELCOME;
1057 			loginmsg = _PATH_FTPLOGINMESG;
1058 
1059 			/*
1060 			 * Preparse the line so we can use its info
1061 			 * for all the addresses associated with
1062 			 * the virtual host name.
1063 			 * Field 0, the virtual host name, is special:
1064 			 * it's already parsed off and will be strdup'ed
1065 			 * later, after we know its canonical form.
1066 			 */
1067 			for (i = 1; i < 5 && (cp = strtok(NULL, " \t")); i++)
1068 				if (*cp != '-' && (cp = strdup(cp)))
1069 					switch (i) {
1070 					case 1:	{ /* anon user permissions */
1071 						char *cp_anondir;
1072 						cp_anondir = strchr(cp, ':');
1073 						if (cp_anondir) {
1074 						    *cp_anondir++ = '\0';
1075 						    anonuser = cp;
1076 						    anondir = cp_anondir;
1077 						} else {
1078 						    anonuser = cp;
1079 						}
1080 						break;
1081 					}
1082 					case 2: /* statistics file */
1083 						statfile = cp;
1084 						break;
1085 					case 3: /* welcome message */
1086 						welcome  = cp;
1087 						break;
1088 					case 4: /* login message */
1089 						loginmsg = cp;
1090 						break;
1091 					default: /* programming error */
1092 						abort();
1093 						/* NOTREACHED */
1094 					}
1095 
1096 			hints.ai_flags = 0;
1097 			hints.ai_family = AF_UNSPEC;
1098 			hints.ai_flags = AI_PASSIVE|AI_CANONNAME;
1099 			if (getaddrinfo(vhost, NULL, &hints, &res) != 0)
1100 				goto nextline;
1101 			for (ai = res; ai != NULL && ai->ai_addr != NULL;
1102 			     ai = ai->ai_next) {
1103 
1104 			gothost = 0;
1105 			for (hrp = firsthost; hrp != NULL; hrp = hrp->next) {
1106 				struct addrinfo *hi;
1107 
1108 				for (hi = hrp->hostinfo; hi != NULL;
1109 				     hi = hi->ai_next)
1110 					if (hi->ai_addrlen == ai->ai_addrlen &&
1111 					    memcmp(hi->ai_addr,
1112 						   ai->ai_addr,
1113 #ifdef LINUX /* Linux port */
1114 						   AI_ADDRLEN(ai)
1115 #else /* BSD source */
1116 						   ai->ai_addr->sa_len
1117 #endif /* BSD source */
1118 						   ) == 0) {
1119 						gothost++;
1120 						break;
1121 					}
1122 				if (gothost)
1123 					break;
1124 			}
1125 			if (hrp == NULL) {
1126 				if ((hrp = malloc(sizeof(struct ftphost))) == NULL)
1127 					goto nextline;
1128 				hrp->hostname = NULL;
1129 				insert = 1;
1130 			} else {
1131 				if (hrp->hostinfo && hrp->hostinfo != res)
1132 					freeaddrinfo(hrp->hostinfo);
1133 				insert = 0; /* host already in the chain */
1134 			}
1135 			hrp->hostinfo = res;
1136 
1137 			/*
1138 			 * determine hostname to use: force canonical name then
1139 			 * it is possible.
1140 			 */
1141 			if(hrp->hostinfo->ai_canonname != NULL)
1142 				vhost = hrp->hostinfo->ai_canonname;
1143 
1144 			if (hrp->hostname &&
1145 			    strcmp(hrp->hostname, vhost) != 0) {
1146 				free(hrp->hostname);
1147 				hrp->hostname = NULL;
1148 			}
1149 			if (hrp->hostname == NULL &&
1150 			    (hrp->hostname = strdup(vhost)) == NULL) {
1151 				freeaddrinfo(hrp->hostinfo);
1152 				hrp->hostinfo = NULL; /* mark as blank */
1153 				goto nextline;
1154 			}
1155 			hrp->anonuser = anonuser;
1156 			hrp->anondir  = anondir;
1157 			hrp->statfile = statfile;
1158 			hrp->welcome  = welcome;
1159 			hrp->loginmsg = loginmsg;
1160 			if (insert) {
1161 				hrp->next  = NULL;
1162 				lhrp->next = hrp;
1163 				lhrp = hrp;
1164 			}
1165 		      }
1166 nextline:
1167 			if (mp)
1168 				free(mp);
1169 		}
1170 		(void) fclose(fp);
1171 	}
1172 }
1173 
1174 static void
selecthost(union sockunion * su)1175 selecthost(union sockunion *su)
1176 {
1177 	struct ftphost	*hrp;
1178 	u_int16_t port;
1179 #ifdef INET6
1180 	struct in6_addr *mapped_in6 = NULL;
1181 #endif
1182 	struct addrinfo *hi;
1183 
1184 #ifdef INET6
1185 	/*
1186 	 * XXX IPv4 mapped IPv6 addr consideraton,
1187 	 * specified in rfc2373.
1188 	 */
1189 	if (su->su_family == AF_INET6 &&
1190 	    IN6_IS_ADDR_V4MAPPED(&su->su_sin6.sin6_addr))
1191 		mapped_in6 = &su->su_sin6.sin6_addr;
1192 #endif
1193 
1194 	hrp = thishost = firsthost;	/* default */
1195 	port = su->su_port;
1196 	su->su_port = 0;
1197 	while (hrp != NULL) {
1198 	    for (hi = hrp->hostinfo; hi != NULL; hi = hi->ai_next) {
1199 		if (memcmp(su, hi->ai_addr,
1200 #ifdef LINUX /* Linux port */
1201 		    AI_ADDRLEN(hi)
1202 #else /* BSD source */
1203 		    hi->ai_addrlen
1204 #endif /* BSD source */
1205 		    ) == 0) {
1206 			thishost = hrp;
1207 			goto found;
1208 		}
1209 #ifdef INET6
1210 		/* XXX IPv4 mapped IPv6 addr consideraton */
1211 		if (hi->ai_addr->sa_family == AF_INET && mapped_in6 != NULL &&
1212 		    (memcmp(&mapped_in6->s6_addr[12],
1213 			    &((struct sockaddr_in *)hi->ai_addr)->sin_addr,
1214 			    sizeof(struct in_addr)) == 0)) {
1215 			thishost = hrp;
1216 			goto found;
1217 		}
1218 #endif /* INET6 */
1219 	    }
1220 	    hrp = hrp->next;
1221 	}
1222 found:
1223 	su->su_port = port;
1224 	/* setup static variables as appropriate */
1225 	hostname = thishost->hostname;
1226 	ftpuser = thishost->anonuser;
1227 }
1228 #endif
1229 
1230 /*
1231  * Helper function for sgetpwnam().
1232  */
1233 static char *
sgetsave(char * s)1234 sgetsave(char *s)
1235 {
1236 	char *new = malloc(strlen(s) + 1);
1237 
1238 	if (new == NULL) {
1239 		reply(421, "Ran out of memory.");
1240 		dologout(1);
1241 		/* NOTREACHED */
1242 	}
1243 	(void) strcpy(new, s);
1244 	return (new);
1245 }
1246 
1247 /*
1248  * Save the result of a getpwnam.  Used for USER command, since
1249  * the data returned must not be clobbered by any other command
1250  * (e.g., globbing).
1251  * NB: The data returned by sgetpwnam() will remain valid until
1252  * the next call to this function.  Its difference from getpwnam()
1253  * is that sgetpwnam() is known to be called from ftpd code only.
1254  */
1255 static struct passwd *
sgetpwnam(char * name)1256 sgetpwnam(char *name)
1257 {
1258 	static struct passwd save;
1259 	struct passwd *p;
1260 #ifdef HAVE_SHADOW_H
1261 	struct spwd *sp;
1262 #endif /* HAVE_SHADOW_H */
1263 
1264 	if ((p = getpwnam(name)) == NULL)
1265 		return (p);
1266 	if (save.pw_name) {
1267 		free(save.pw_name);
1268 		free(save.pw_passwd);
1269 		free(save.pw_gecos);
1270 		free(save.pw_dir);
1271 		free(save.pw_shell);
1272 	}
1273 	save = *p;
1274 	save.pw_name = sgetsave(p->pw_name);
1275 #ifdef HAVE_SHADOW_H
1276 	if ((sp = getspnam(p->pw_name)) != NULL) {
1277 		save.pw_passwd = sgetsave(sp->sp_pwdp);
1278 	} else
1279 #endif /* HAVE_SHADOW_H */
1280 	save.pw_passwd = sgetsave(p->pw_passwd);
1281 	save.pw_gecos = sgetsave(p->pw_gecos);
1282 	save.pw_dir = sgetsave(p->pw_dir);
1283 	save.pw_shell = sgetsave(p->pw_shell);
1284 	return (&save);
1285 }
1286 
1287 static int login_attempts;	/* number of failed login attempts */
1288 static int askpasswd;		/* had user command, ask for passwd */
1289 static char curname[MAXLOGNAME];	/* current USER name */
1290 
1291 /*
1292  * USER command.
1293  * Sets global passwd pointer pw if named account exists and is acceptable;
1294  * sets askpasswd if a PASS command is expected.  If logged in previously,
1295  * need to reset state.  If name is "ftp" or "anonymous", the name is not in
1296  * _PATH_FTPUSERS, and ftp account exists, set guest and pw, then just return.
1297  * If account doesn't exist, ask for passwd anyway.  Otherwise, check user
1298  * requesting login privileges. Disallow anyone mentioned in the file
1299  * _PATH_FTPUSERS to allow people such as root and uucp to be avoided.
1300  */
1301 void
user(char * name)1302 user(char *name)
1303 {
1304 	if (logged_in) {
1305 		if (guest) {
1306 			reply(530, "Can't change user from guest login.");
1307 			return;
1308 		} else if (dochroot) {
1309 			reply(530, "Can't change user from chroot user.");
1310 			return;
1311 		}
1312 		end_login();
1313 	}
1314 
1315 	guest = 0;
1316 #ifdef VIRTUAL_HOSTING
1317 	pw = sgetpwnam(thishost->anonuser);
1318 #else
1319 	pw = sgetpwnam("ftp");
1320 #endif
1321 	if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) {
1322 		if (checkuser(_PATH_FTPUSERS, "ftp", 0, NULL) ||
1323 		    checkuser(_PATH_FTPUSERS, "anonymous", 0, NULL))
1324 			reply(530, "User %s access denied.", name);
1325 #ifdef USE_SSL /* policy checking */
1326 		else {
1327 			/* Deny anonymous access over secure session. */
1328 			if (ssl_active_flag && ssl_dpau_flag) {
1329 				reply(534,
1330 			    "User %s secure access denied for policy reasons.",
1331 				name);
1332 			}
1333 #endif /* USE_SSL */
1334 		else if (pw != NULL) {
1335 			guest = 1;
1336 			askpasswd = 1;
1337 			reply(331,
1338 			"Guest login ok, send your email address as password.");
1339 		} else
1340 			reply(530, "User %s unknown.", name);
1341 #ifdef USE_SSL /* policy checking */
1342 		}
1343 #endif /* USE_SSL */
1344 		if (!askpasswd && logging)
1345 			syslog(LOG_NOTICE,
1346 #ifdef USE_SSL
1347 			    "%sANONYMOUS FTP LOGIN REFUSED FROM %s",
1348 			    ssl_active_flag ? "SECURE " : "", remotehost);
1349 #else /* !USE_SSL */
1350 			    "ANONYMOUS FTP LOGIN REFUSED FROM %s", remotehost);
1351 #endif /* USE_SSL */
1352 		return;
1353 	}
1354 	if (anon_only != 0) {
1355 		reply(530, "Sorry, only anonymous ftp allowed.");
1356 		return;
1357 	}
1358 
1359 #ifdef USE_SSL /* policy checking */
1360 	/* Deny non-anonymous access over non-secure session. */
1361 	if (!ssl_active_flag && ssl_rpnu_flag) {
1362 		reply(534,
1363 		    "User %s non-secure access denied for policy reasons.",
1364 		    name);
1365 		if (logging)
1366 			syslog(LOG_NOTICE,
1367 			    "NON-SECURE FTP LOGIN REFUSED FROM %s, %s",
1368 			    remotehost, name);
1369 		return;
1370 	}
1371 #endif /* USE_SSL */
1372 
1373 	pw = sgetpwnam(name);
1374 	if (checkuser(_PATH_FTPUSERS, name, pw != NULL ? 1 : 0, NULL)) {
1375 		reply(530, "User %s access denied.", name);
1376 		if (logging)
1377 			syslog(LOG_NOTICE,
1378 			    "FTP LOGIN REFUSED FROM %s, %s (name is in %s)",
1379 			    remotehost, name, _PATH_FTPUSERS);
1380 		pw = NULL;
1381 		return;
1382 	}
1383 	snprintf(curname, sizeof(curname), "%s", name);
1384 
1385 #ifdef USE_SSL
1386 	/* Do X.509 auth of TLS/SSL client, if possible. */
1387 	if (ssl_active_flag && pw && good_ssl_user(name)) {
1388 		x509_auth_ok = 1;
1389 	}
1390 	/*
1391 	 * Fallback to the standard auth if X.509 auth isn't sufficient or
1392 	 * is impossible.
1393 	 */
1394 	if (x509_auth_fallback_status()) {
1395 #endif /* USE_SSL */
1396 	/*
1397 	 * Delay before reading passwd after first failed
1398 	 * attempt to slow down passwd-guessing programs.
1399 	 */
1400 	if (login_attempts) {
1401 		sigset_t oset, nset;
1402 
1403 		sigfillset(&nset);
1404 		sigprocmask(SIG_BLOCK, &nset, &oset);
1405 		sleep(login_attempts);
1406 		sigprocmask(SIG_SETMASK, &oset, NULL);
1407 	}
1408 
1409 #ifdef HAVE_OPIE
1410 	pwok = 0;
1411 #ifdef USE_PAM
1412 	/* XXX Kluge! The conversation mechanism needs to be fixed. */
1413 #endif
1414 	if (opiechallenge(&opiedata, name, opieprompt) == 0) {
1415 		pwok = (pw != NULL) &&
1416 		       opieaccessfile(remotehost) &&
1417 		       opiealways(pw->pw_dir);
1418 		reply(331, "Response to %s %s for %s.",
1419 		      opieprompt, pwok ? "requested" : "required", name);
1420 	} else {
1421 		pwok = 1;
1422 		reply(331, "Password required for %s.", name);
1423 	}
1424 #else /* !HAVE_OPIE */
1425 	reply(331, "Password required for %s.", name);
1426 #endif /* HAVE_OPIE */
1427 #ifdef USE_SSL
1428 	}
1429 	/*
1430 	 * Now do the common part for both X.509-silent and standard auth.
1431 	 */
1432 #endif /* USE_SSL */
1433 	askpasswd = 1;
1434 #ifdef USE_SSL
1435 	/* Do X.509 auth of TLS/SSL client without asking user password. */
1436 	if (!x509_auth_fallback_status()) {
1437 		pass("X.509"); /* send dummy password to login */
1438 	}
1439 #endif /* USE_SSL */
1440 }
1441 
1442 /*
1443  * Check if a user is in the file "fname",
1444  * return a pointer to a malloc'd string with the rest
1445  * of the matching line in "residue" if not NULL.
1446  */
1447 static int
checkuser(char * fname,char * name,int pwset,char ** residue)1448 checkuser(char *fname, char *name, int pwset, char **residue)
1449 {
1450 	FILE *fd;
1451 	int found = 0;
1452 	size_t len;
1453 	char *line, *mp, *p;
1454 
1455 	if ((fd = fopen(fname, "r")) != NULL) {
1456 		while (!found && (line = fgetln(fd, &len)) != NULL) {
1457 			/* skip comments */
1458 			if (line[0] == '#')
1459 				continue;
1460 			if (line[len - 1] == '\n') {
1461 				line[len - 1] = '\0';
1462 				mp = NULL;
1463 			} else {
1464 				if ((mp = malloc(len + 1)) == NULL)
1465 					fatalerror("Ran out of memory.");
1466 				memcpy(mp, line, len);
1467 				mp[len] = '\0';
1468 				line = mp;
1469 			}
1470 			/* avoid possible leading and trailing whitespace */
1471 			p = strtok(line, " \t");
1472 			/* skip empty lines */
1473 			if (p == NULL)
1474 				goto nextline;
1475 			/*
1476 			 * if first chr is '@', check group membership
1477 			 */
1478 			if (p[0] == '@') {
1479 				int i = 0;
1480 				struct group *grp;
1481 
1482 				if (p[1] == '\0') /* single @ matches anyone */
1483 					found = 1;
1484 				else {
1485 					if ((grp = getgrnam(p+1)) == NULL)
1486 						goto nextline;
1487 					/*
1488 					 * Check user's default group
1489 					 */
1490 					if (pwset && grp->gr_gid == pw->pw_gid)
1491 						found = 1;
1492 					/*
1493 					 * Check supplementary groups
1494 					 */
1495 					while (!found && grp->gr_mem[i])
1496 						found = strcmp(name,
1497 							grp->gr_mem[i++])
1498 							== 0;
1499 				}
1500 			}
1501 			/*
1502 			 * Otherwise, just check for username match
1503 			 */
1504 			else
1505 				found = strcmp(p, name) == 0;
1506 			/*
1507 			 * Save the rest of line to "residue" if matched
1508 			 */
1509 			if (found && residue) {
1510 				if ((p = strtok(NULL, "")) != NULL)
1511 					p += strspn(p, " \t");
1512 				if (p && *p) {
1513 				 	if ((*residue = strdup(p)) == NULL)
1514 						fatalerror("Ran out of memory.");
1515 				} else
1516 					*residue = NULL;
1517 			}
1518 nextline:
1519 			if (mp)
1520 				free(mp);
1521 		}
1522 		(void) fclose(fd);
1523 	}
1524 	return (found);
1525 }
1526 
1527 /*
1528  * Terminate login as previous user, if any, resetting state;
1529  * used when USER command is given or login fails.
1530  */
1531 static void
end_login(void)1532 end_login(void)
1533 {
1534 #ifdef USE_PAM
1535 	int e;
1536 #endif
1537 
1538 	(void) seteuid(0);
1539 	if (logged_in && dowtmp)
1540 		ftpd_logwtmp(ttyline, "", NULL);
1541 	pw = NULL;
1542 #ifdef	LOGIN_CAP
1543 	setusercontext(NULL, getpwuid(0), 0,
1544 		       LOGIN_SETPRIORITY|LOGIN_SETRESOURCES|LOGIN_SETUMASK
1545 #ifdef HAVE_MAC
1546 		       |LOGIN_SETMAC
1547 #endif /* HAVE_MAC */
1548 		       );
1549 #endif /* LOGIN_CAP */
1550 #ifdef USE_PAM
1551 	if (pamh) {
1552 		if ((e = pam_setcred(pamh, PAM_DELETE_CRED)) != PAM_SUCCESS)
1553 			syslog(LOG_ERR, "pam_setcred: %s", pam_strerror(pamh, e));
1554 		if ((e = pam_close_session(pamh,0)) != PAM_SUCCESS)
1555 			syslog(LOG_ERR, "pam_close_session: %s", pam_strerror(pamh, e));
1556 		if ((e = pam_end(pamh, e)) != PAM_SUCCESS)
1557 			syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, e));
1558 		pamh = NULL;
1559 		/* Reset the logging facility because it may be changed by PAM
1560 		 * modules. */
1561 		ftpd_openlog();
1562 	}
1563 #endif /* USE_PAM */
1564 	logged_in = 0;
1565 	guest = 0;
1566 	dochroot = 0;
1567 #ifdef USE_SSL
1568 	x509_auth_ok = 0;
1569 #endif
1570 }
1571 
1572 #ifdef USE_PAM
1573 
1574 /*
1575  * the following code is stolen from imap-uw PAM authentication module and
1576  * login.c
1577  */
1578 #define COPY_STRING(s) (s ? strdup(s) : NULL)
1579 
1580 struct cred_t {
1581 	const char *uname;		/* user name */
1582 	const char *pass;		/* password */
1583 };
1584 typedef struct cred_t cred_t;
1585 
1586 static int
auth_conv(int num_msg,const struct pam_message ** msg,struct pam_response ** resp,void * appdata)1587 auth_conv(int num_msg, const struct pam_message **msg,
1588 	  struct pam_response **resp, void *appdata)
1589 {
1590 	int i;
1591 	cred_t *cred = (cred_t *) appdata;
1592 	struct pam_response *reply;
1593 
1594 	reply = calloc(num_msg, sizeof *reply);
1595 	if (reply == NULL)
1596 		return PAM_BUF_ERR;
1597 
1598 	for (i = 0; i < num_msg; i++) {
1599 		switch (msg[i]->msg_style) {
1600 		case PAM_PROMPT_ECHO_ON:	/* assume want user name */
1601 			reply[i].resp_retcode = PAM_SUCCESS;
1602 			reply[i].resp = COPY_STRING(cred->uname);
1603 			/* PAM frees resp. */
1604 			break;
1605 		case PAM_PROMPT_ECHO_OFF:	/* assume want password */
1606 			reply[i].resp_retcode = PAM_SUCCESS;
1607 			reply[i].resp = COPY_STRING(cred->pass);
1608 			/* PAM frees resp. */
1609 			break;
1610 		case PAM_TEXT_INFO:
1611 		case PAM_ERROR_MSG:
1612 			reply[i].resp_retcode = PAM_SUCCESS;
1613 			reply[i].resp = NULL;
1614 			break;
1615 		default:			/* unknown message style */
1616 			free(reply);
1617 			return PAM_CONV_ERR;
1618 		}
1619 	}
1620 
1621 	*resp = reply;
1622 	return PAM_SUCCESS;
1623 }
1624 
1625 /*
1626  * Attempt to authenticate the user using PAM.  Returns 0 if the user is
1627  * authenticated, or 1 if not authenticated.  If some sort of PAM system
1628  * error occurs (e.g., the "/etc/pam.conf" file is missing) then this
1629  * function returns -1.  This can be used as an indication that we should
1630  * fall back to a different authentication mechanism.
1631  */
1632 static int
auth_pam(struct passwd ** ppw,const char * pass)1633 auth_pam(struct passwd **ppw, const char *pass)
1634 {
1635 	char *tmpl_user;
1636 	const void *item;
1637 	int rval;
1638 	int e;
1639 	cred_t auth_cred = { (*ppw)->pw_name, pass };
1640 	struct pam_conv conv = { &auth_conv, &auth_cred };
1641 
1642 	e = pam_start(_SERVICE_NAME, (*ppw)->pw_name, &conv, &pamh);
1643 	if (e != PAM_SUCCESS) {
1644 		syslog(LOG_ERR, "pam_start: %s", pam_strerror(pamh, e));
1645 		/* pamh is NULL, so don't call pam_end() */
1646 		return -1;
1647 	}
1648 
1649 	e = pam_set_item(pamh, PAM_RHOST, remotehost);
1650 	if (e != PAM_SUCCESS) {
1651 		syslog(LOG_ERR, "pam_set_item(PAM_RHOST): %s",
1652 			pam_strerror(pamh, e));
1653 		if ((e = pam_end(pamh, e)) != PAM_SUCCESS) {
1654 			syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, e));
1655 		}
1656 		pamh = NULL;
1657 		return -1;
1658 	}
1659 
1660 #ifdef USE_SSL
1661 	/*
1662 	 * If X.509 auth was successful and fallback to standard auth
1663 	 * isn't required, skip all auth management modules.
1664 	 */
1665 	if (x509_auth_fallback_status()) {
1666 #endif
1667 	e = pam_authenticate(pamh, 0);
1668 	switch (e) {
1669 	case PAM_SUCCESS:
1670 		/*
1671 		 * With PAM we support the concept of a "template"
1672 		 * user.  The user enters a login name which is
1673 		 * authenticated by PAM, usually via a remote service
1674 		 * such as RADIUS or TACACS+.  If authentication
1675 		 * succeeds, a different but related "template" name
1676 		 * is used for setting the credentials, shell, and
1677 		 * home directory.  The name the user enters need only
1678 		 * exist on the remote authentication server, but the
1679 		 * template name must be present in the local password
1680 		 * database.
1681 		 *
1682 		 * This is supported by two various mechanisms in the
1683 		 * individual modules.  However, from the application's
1684 		 * point of view, the template user is always passed
1685 		 * back as a changed value of the PAM_USER item.
1686 		 */
1687 		if ((e = pam_get_item(pamh, PAM_USER, &item)) ==
1688 		    PAM_SUCCESS) {
1689 			tmpl_user = (char *) item;
1690 			if (strcmp((*ppw)->pw_name, tmpl_user) != 0)
1691 				*ppw = sgetpwnam(tmpl_user);
1692 		} else
1693 			syslog(LOG_ERR, "Couldn't get PAM_USER: %s",
1694 			    pam_strerror(pamh, e));
1695 		rval = 0;
1696 		break;
1697 
1698 	case PAM_AUTH_ERR:
1699 	case PAM_USER_UNKNOWN:
1700 	case PAM_MAXTRIES:
1701 		rval = 1;
1702 		break;
1703 
1704 	default:
1705 		syslog(LOG_ERR, "pam_authenticate: %s", pam_strerror(pamh, e));
1706 		rval = -1;
1707 		break;
1708 	}
1709 #ifdef USE_SSL
1710 	} else {
1711 		rval = 0;
1712 	}
1713 #endif
1714 
1715 	if (rval == 0) {
1716 		e = pam_acct_mgmt(pamh, 0);
1717 		if (e != PAM_SUCCESS) {
1718 			syslog(LOG_ERR, "pam_acct_mgmt: %s",
1719 						pam_strerror(pamh, e));
1720 			rval = 1;
1721 		}
1722 	}
1723 
1724 	if (rval != 0) {
1725 		if ((e = pam_end(pamh, e)) != PAM_SUCCESS) {
1726 			syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, e));
1727 		}
1728 		pamh = NULL;
1729 	}
1730 	return rval;
1731 }
1732 
1733 #endif /* USE_PAM */
1734 
1735 void
pass(char * passwd)1736 pass(char *passwd)
1737 {
1738 	int rval;
1739 	FILE *fd;
1740 #ifdef	LOGIN_CAP
1741 	login_cap_t *lc = NULL;
1742 #endif
1743 #ifdef USE_PAM
1744 	int e;
1745 #endif
1746 	char *residue = NULL;
1747 	char *xpasswd;
1748 #ifdef HAVE_SHADOW_H
1749 	struct spwd *sp;
1750 #endif /* HAVE_SHADOW_H */
1751 
1752 
1753 	if (logged_in || askpasswd == 0) {
1754 		reply(503, "Login with USER first.");
1755 		return;
1756 	}
1757 	askpasswd = 0;
1758 	if (!guest) {		/* "ftp" is only account allowed no password */
1759 #ifdef USE_SSL
1760 		/*
1761 		 * If X.509 auth of TLS/SSL client is required in any case,
1762 		 * but failed, don't fallback to standard auth; the overall
1763 		 * auth is failed.
1764 		 */
1765 		if (ssl_active_flag && !x509_auth_ok &&
1766 		    ((x509_auth_flag == X509_AUTH_REQUIRED) ||
1767 		    (x509_auth_flag == X509_AND_STANDARD_AUTH))) {
1768 			rval = 1;
1769  			goto skip;
1770 		}
1771 #endif /* USE_SSL */
1772 #ifdef USE_PAM
1773 		/*
1774 		 * PAM authentication.
1775 		 */
1776 		if (pw == NULL) {
1777 			/* Try to use a "template" user account. */
1778 			struct passwd tpw, *ppw = &tpw;
1779 
1780 			tpw.pw_name = strdup(curname);
1781 			if (tpw.pw_name == NULL)
1782 				fatalerror("Ran out of memory.");
1783 
1784 			rval = auth_pam(&ppw, passwd);
1785 
1786 			/* If the initial value of the user name was changed
1787 			 * by PAM, try to use the new name as the "template"
1788 			 * user account. */
1789 			if (rval == 0) {
1790 				if ((ppw == NULL) ||
1791 				    (strcmp(ppw->pw_name, curname) == 0)) {
1792 					/* The "template" account doesn't exist
1793 					 * or it wasn't passed back by PAM. */
1794 					rval = 1;
1795 				} else {
1796 					/* Use the "template" account. */
1797 					pw = ppw;
1798 				}
1799 			}
1800 			free(tpw.pw_name);
1801 		} else {
1802 			/* Normal PAM auth. */
1803 			rval = auth_pam(&pw, passwd);
1804 		}
1805 
1806 		/* Reset the logging facility because it may be changed by PAM
1807 		 * modules. */
1808 		ftpd_openlog();
1809 
1810 		if ((pw != NULL) && logging) {
1811 			if (strcmp(pw->pw_name, curname) != 0)
1812 				syslog(LOG_NOTICE,
1813 				    "PAM template user account is: %s",
1814 				    pw->pw_name);
1815 		}
1816 
1817 		if (rval >= 0) {
1818 #ifdef HAVE_OPIE
1819 			opieunlock();
1820 #endif /* HAVE_OPIE */
1821 			goto skip;
1822 		}
1823 #endif /* USE_PAM */
1824 		/*
1825 		 * Traditional UNIX authentication.
1826 		 */
1827 		if (pw == NULL) {
1828 			rval = 1;	/* failure below */
1829 			goto skip;
1830 		}
1831 #ifdef USE_SSL /* X.509 auth support without PAM */
1832 		if (x509_auth_fallback_status()) {
1833 #endif /* USE_SSL */
1834 #ifdef HAVE_OPIE
1835 		if (opieverify(&opiedata, passwd) == 0)
1836 			xpasswd = pw->pw_passwd;
1837 		else if (pwok) {
1838 #endif /* HAVE_OPIE */
1839 		xpasswd = crypt(passwd, pw->pw_passwd);
1840 		if (passwd[0] == '\0' && pw->pw_passwd[0] != '\0')
1841 			xpasswd = ":";
1842 #ifdef HAVE_OPIE
1843 		} else {
1844 			rval = 1;
1845 			goto skip;
1846 		}
1847 #endif /* HAVE_OPIE */
1848 		rval = strcmp(pw->pw_passwd, xpasswd);
1849 #ifdef USE_SSL /* X.509 auth support without PAM */
1850 		} else {
1851 			rval = 0;
1852 		}
1853 #endif /* USE_SSL */
1854 #ifdef HAVE_SHADOW_H /* SysV-style passwd/shadow implementation used in Linux */
1855 		if ((sp = getspnam(pw->pw_name)) != NULL) {
1856 			if (sp->sp_expire && time(NULL) >= sp->sp_expire)
1857 				rval = 1;	/* failure */
1858 		}
1859 #else /* BSD-style passwd/master.passwd implementation */
1860 		if (pw->pw_expire && time(NULL) >= pw->pw_expire)
1861 			rval = 1;	/* failure */
1862 #endif /* HAVE_SHADOW_H */
1863 skip:
1864 		/*
1865 		 * If rval == 1, the user failed the authentication check
1866 		 * above.  If rval == 0, either PAM or local authentication
1867 		 * succeeded.
1868 		 */
1869 		if (rval) {
1870 			reply(530, "Login incorrect.");
1871 			if (logging) {
1872 				syslog(LOG_NOTICE,
1873 				    "FTP LOGIN FAILED FROM %s (attempt %d)",
1874 				    remotehost, login_attempts + 1);
1875 				syslog(LOG_AUTHPRIV | LOG_NOTICE,
1876 				    "FTP LOGIN FAILED FROM %s, %s (attempt %d)",
1877 				    remotehost, curname, login_attempts + 1);
1878 			}
1879 			pw = NULL;
1880 			if (login_attempts++ >= 5) {
1881 				syslog(LOG_NOTICE,
1882 				    "repeated login failures from %s",
1883 				    remotehost);
1884 				dologout(0);
1885 			}
1886 			return;
1887 		} else {
1888 			/*
1889 			 * Disallow anyone who does not have a standard shell
1890 			 * as returned by getusershell(). This check is
1891 			 * performed in the last step of the authentication to
1892 			 * prevent the username enumeration.
1893 			 */
1894 			char *cp, *shell;
1895 			if ((shell = pw->pw_shell) == NULL || *shell == 0)
1896 				shell = _PATH_BSHELL;
1897 			setusershell();
1898 			while ((cp = getusershell()) != NULL)
1899 				if (strcmp(cp, shell) == 0)
1900 					break;
1901 			endusershell();
1902 
1903 			if (cp == NULL) {
1904 				reply(530, "User %s access denied.", curname);
1905 				if (logging)
1906 					syslog(LOG_NOTICE,
1907 					    "FTP LOGIN REFUSED FROM %s, %s (shell is not in /etc/shells)",
1908 					    remotehost, curname);
1909 				/* SKYNICK: "return" is also possible */
1910 				dologout(0);
1911 			}
1912 		}
1913 	}
1914 	login_attempts = 0;		/* this time successful */
1915 	if (setegid(pw->pw_gid) < 0) {
1916 		reply(550, "Can't set gid.");
1917 		return;
1918 	}
1919 	/* May be overridden by login.conf */
1920 	(void) umask(defumask);
1921 #ifdef	LOGIN_CAP
1922 	if ((lc = login_getpwclass(pw)) != NULL) {
1923 		char	remote_ip[NI_MAXHOST];
1924 
1925 		if (getnameinfo((struct sockaddr *)&his_addr, his_addr.su_len,
1926 			remote_ip, sizeof(remote_ip) - 1, NULL, 0,
1927 			NI_NUMERICHOST))
1928 				*remote_ip = 0;
1929 		remote_ip[sizeof(remote_ip) - 1] = 0;
1930 		if (!auth_hostok(lc, remotehost, remote_ip)) {
1931 			syslog(LOG_INFO|LOG_AUTH,
1932 			    "FTP LOGIN FAILED (HOST) as %s: permission denied.",
1933 			    curname);
1934 			reply(530, "Permission denied.");
1935 			pw = NULL;
1936 			return;
1937 		}
1938 		if (!auth_timeok(lc, time(NULL))) {
1939 			reply(530, "Login not available right now.");
1940 			pw = NULL;
1941 			return;
1942 		}
1943 	}
1944 	setusercontext(lc, pw, 0,
1945 		LOGIN_SETLOGIN|LOGIN_SETGROUP|LOGIN_SETPRIORITY|
1946 		LOGIN_SETRESOURCES|LOGIN_SETUMASK
1947 #ifdef HAVE_MAC
1948 		|LOGIN_SETMAC
1949 #endif
1950 		);
1951 #else /* !LOGIN_CAP */
1952 #ifndef LINUX /* BSD source */
1953 	setlogin(pw->pw_name);
1954 #endif /* BSD source */
1955 	(void) initgroups(pw->pw_name, pw->pw_gid);
1956 #endif /* LOGIN_CAP */
1957 
1958 #ifdef USE_PAM
1959 	if (pamh) {
1960 		if ((e = pam_open_session(pamh, 0)) != PAM_SUCCESS) {
1961 			syslog(LOG_ERR, "pam_open_session: %s", pam_strerror(pamh, e));
1962 		} else if ((e = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS) {
1963 			syslog(LOG_ERR, "pam_setcred: %s", pam_strerror(pamh, e));
1964 		}
1965 		/* Reset the logging facility because it may be changed by PAM
1966 		 * modules. */
1967 		ftpd_openlog();
1968 	}
1969 #endif /* USE_PAM */
1970 
1971 	/* open wtmp before chroot */
1972 	if (dowtmp)
1973 		ftpd_logwtmp(ttyline, curname,
1974 		    (struct sockaddr *)&his_addr);
1975 	logged_in = 1;
1976 
1977 	if ((stats || xferlog_stat) && statfd < 0)
1978 #ifdef VIRTUAL_HOSTING
1979 		statfd = open(thishost->statfile, O_WRONLY|O_APPEND);
1980 #else
1981 		statfd = open(_PATH_FTPDSTATFILE, O_WRONLY|O_APPEND);
1982 #endif
1983 		if (statfd < 0) {
1984 			stats = 0;
1985 			xferlog_stat = 0;
1986 		}
1987 
1988 	dochroot =
1989 		checkuser(_PATH_FTPCHROOT, pw->pw_name, 1, &residue)
1990 #ifdef	LOGIN_CAP	/* Allow login.conf configuration as well */
1991 		|| login_getcapbool(lc, "ftp-chroot", 0)
1992 #endif
1993 	;
1994 	chrootdir = NULL;
1995 	/*
1996 	 * For a chrooted local user,
1997 	 * a) see whether ftpchroot(5) specifies a chroot directory,
1998 	 * b) extract the directory pathname from the line,
1999 	 * c) expand it to the absolute pathname if necessary.
2000 	 */
2001 	if (dochroot && residue &&
2002 	    (chrootdir = strtok(residue, " \t")) != NULL) {
2003 		if (chrootdir[0] != '/')
2004 			asprintf(&chrootdir, "%s/%s", pw->pw_dir, chrootdir);
2005 		else
2006 			chrootdir = strdup(chrootdir); /* make it permanent */
2007 		if (chrootdir == NULL)
2008 			fatalerror("Ran out of memory.");
2009 	}
2010 #ifdef VIRTUAL_HOSTING
2011 	/*
2012 	 * The anonymous ftp area of the virtual host from /etc/ftphosts, if
2013 	 * it is specified, overrides all possible values of the chroot
2014 	 * directory for anonymous ftp account (home directory, the directory
2015 	 * from ftpchroot(5)).
2016 	 * Copy thishost->anondir so it can be modified while the original
2017 	 * value stays intact. Also expand it to the absolute pathname if
2018 	 * necessary.
2019 	 */
2020 	if (guest && thishost->anondir != NULL) {
2021 		char *ctemp;
2022 
2023 		ctemp = NULL;
2024 		if (chrootdir)
2025 			free(chrootdir);
2026 
2027 		if ((ctemp = strdup(thishost->anondir)) == NULL)
2028 			fatalerror("Ran out of memory.");
2029 		if (ctemp[0] != '/') {
2030 			asprintf(&chrootdir, "%s/%s", pw->pw_dir, ctemp);
2031 			if (chrootdir == NULL)
2032 				fatalerror("Ran out of memory.");
2033 		} else {
2034 			if ((chrootdir = strdup(ctemp)) == NULL)
2035 				fatalerror("Ran out of memory.");
2036 		}
2037 
2038 		if (ctemp)
2039 			free(ctemp);
2040 	}
2041 #endif /* VIRTUAL_HOSTING */
2042 	if (guest || dochroot) {
2043 		/*
2044 		 * If no chroot directory set yet, use the login directory.
2045 		 * Copy it so it can be modified while pw->pw_dir stays intact.
2046 		 */
2047 		if (chrootdir == NULL &&
2048 		    (chrootdir = strdup(pw->pw_dir)) == NULL)
2049 			fatalerror("Ran out of memory.");
2050 		/*
2051 		 * Check for the "/chroot/./home" syntax,
2052 		 * separate the chroot and home directory pathnames.
2053 		 */
2054 		if ((homedir = strstr(chrootdir, "/./")) != NULL) {
2055 			*(homedir++) = '\0';	/* wipe '/' */
2056 			homedir++;		/* skip '.' */
2057 		} else {
2058 			/*
2059 			 * We MUST do a chdir() after the chroot. Otherwise
2060 			 * the old current directory will be accessible as "."
2061 			 * outside the new root!
2062 			 */
2063 			homedir = "/";
2064 		}
2065 		/* Sanity checking... */
2066 		if (realpath(chrootdir, rchrootdir) == NULL) {
2067 			syslog(LOG_WARNING, "realpath failed on '%s': %m", rchrootdir);
2068 			reply(550, "Can't change root.");
2069 			goto bad;
2070 		}
2071 		/*
2072 		 * Finally, do chroot()
2073 		 */
2074 		if (chroot(chrootdir) < 0) {
2075 			reply(550, "Can't change root.");
2076 			goto bad;
2077 		}
2078 	} else	/* real user w/o chroot */
2079 		homedir = pw->pw_dir;
2080 	/*
2081 	 * Set euid *before* doing chdir() so
2082 	 * a) the user won't be carried to a directory that he couldn't reach
2083 	 *    on his own due to no permission to upper path components,
2084 	 * b) NFS mounted homedirs w/restrictive permissions will be accessible
2085 	 *    (uid 0 has no root power over NFS if not mapped explicitly.)
2086 	 */
2087 	if (seteuid(pw->pw_uid) < 0) {
2088 		reply(550, "Can't set uid.");
2089 		goto bad;
2090 	}
2091 	if (chdir(homedir) < 0) {
2092 		if (guest || dochroot) {
2093 			reply(550, "Can't change to base directory.");
2094 			goto bad;
2095 		} else {
2096 			if (chdir("/") < 0) {
2097 				reply(550, "Root is inaccessible.");
2098 				goto bad;
2099 			}
2100 			lreply(230, "No directory! Logging in with home=/.");
2101 		}
2102 	}
2103 
2104 	/*
2105 	 * Display a login message, if it exists.
2106 	 * N.B. reply(230,) must follow the message.
2107 	 */
2108 #ifdef VIRTUAL_HOSTING
2109 	fd = fopen(thishost->loginmsg, "r");
2110 #else
2111 	fd = fopen(_PATH_FTPLOGINMESG, "r");
2112 #endif
2113 	if (fd != NULL) {
2114 		char *cp, line[LINE_MAX];
2115 
2116 		while (fgets(line, sizeof(line), fd) != NULL) {
2117 			if ((cp = strchr(line, '\n')) != NULL)
2118 				*cp = '\0';
2119 			lreply(230, "%s", line);
2120 		}
2121 		(void) FFLUSH(stdout);
2122 		(void) fclose(fd);
2123 	}
2124 	if (guest) {
2125 		if (ident != NULL)
2126 			free(ident);
2127 		ident = strdup(passwd);
2128 		if (ident == NULL)
2129 			fatalerror("Ran out of memory.");
2130 
2131 		reply(230, "Guest login ok, access restrictions apply.");
2132 #ifdef SETPROCTITLE
2133 #ifdef VIRTUAL_HOSTING
2134 		if (thishost != firsthost)
2135 			snprintf(proctitle, sizeof(proctitle),
2136 				 "%s: anonymous(%s)/%s", remotehost, hostname,
2137 				 passwd);
2138 		else
2139 #endif
2140 			snprintf(proctitle, sizeof(proctitle),
2141 				 "%s: anonymous/%s", remotehost, passwd);
2142 		setproctitle("%s", proctitle);
2143 #endif /* SETPROCTITLE */
2144 		if (logging)
2145 			syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s, %s",
2146 			    remotehost, passwd);
2147 	} else {
2148 #ifndef USE_SSL /* !USE_SSL */
2149 		if (dochroot)
2150 			reply(230, "User %s logged in, "
2151 				   "access restrictions apply.", curname);
2152 		else
2153 			reply(230, "User %s logged in.", curname);
2154 #else /* USE_SSL */
2155 		if (dochroot)
2156 			reply(x509_auth_fallback_status() ? 230 : 232,
2157 			    "User %s logged in, access restrictions apply.",
2158 			    curname);
2159 		else
2160 			reply(x509_auth_fallback_status() ? 230 : 232,
2161 			    "User %s logged in.", curname);
2162 #endif /* !USE_SSL */
2163 
2164 #ifdef SETPROCTITLE
2165 		snprintf(proctitle, sizeof(proctitle),
2166 			 "%s: user/%s", remotehost, curname);
2167 		setproctitle("%s", proctitle);
2168 #endif /* SETPROCTITLE */
2169 		if (logging)
2170 			syslog(LOG_INFO, "FTP LOGIN FROM %s as %s",
2171 			    remotehost, curname);
2172 	}
2173 	if (logging && (guest || dochroot))
2174 		syslog(LOG_INFO, "session root changed to '%s' (realpath: '%s')",
2175 		      chrootdir, rchrootdir);
2176 #ifdef	LOGIN_CAP
2177 	login_close(lc);
2178 #endif
2179 	if (residue)
2180 		free(residue);
2181 	return;
2182 bad:
2183 	/* Forget all about it... */
2184 #ifdef	LOGIN_CAP
2185 	login_close(lc);
2186 #endif
2187 	if (residue)
2188 		free(residue);
2189 	end_login();
2190 }
2191 
2192 void
retrieve(char * cmd,char * name)2193 retrieve(char *cmd, char *name)
2194 {
2195 	FILE *fin, *dout;
2196 	struct stat st;
2197 	int (*closefunc)(FILE *);
2198 	time_t time_start, time_end;
2199 	int send_err = -1;
2200 
2201 	/* Set the default values */
2202 	time(&time_start);
2203 	time_end = time_start;
2204 
2205 	if (cmd == 0) {
2206 		fin = fopen(name, "r"), closefunc = fclose;
2207 		st.st_size = 0;
2208 	} else {
2209 		char line[BUFSIZ];
2210 
2211 		(void) snprintf(line, sizeof(line), cmd, name), name = line;
2212 		fin = ftpd_popen(line, "r"), closefunc = ftpd_pclose;
2213 		st.st_size = -1;
2214 		st.st_blksize = BUFSIZ;
2215 	}
2216 	if (fin == NULL) {
2217 		if (errno != 0) {
2218 			perror_reply(550, name);
2219 			if (cmd == 0) {
2220 				LOGCMD("get", name);
2221 			}
2222 		}
2223 		return;
2224 	}
2225 	byte_count = -1;
2226 	if (cmd == 0) {
2227 		if (fstat(fileno(fin), &st) < 0) {
2228 			perror_reply(550, name);
2229 			goto done;
2230 		}
2231 		if (!S_ISREG(st.st_mode)) {
2232 			/*
2233 			 * Never sending a raw directory is a workaround
2234 			 * for buggy clients that will attempt to RETR
2235 			 * a directory before listing it, e.g., Mozilla.
2236 			 * Preventing a guest from getting irregular files
2237 			 * is a simple security measure.
2238 			 */
2239 			if (S_ISDIR(st.st_mode) || guest) {
2240 				reply(550, "%s: not a plain file.", name);
2241 				goto done;
2242 			}
2243 			st.st_size = -1;
2244 			/* st.st_blksize is set for all descriptor types */
2245 		}
2246 	}
2247 	if (restart_point) {
2248 		if (type == TYPE_A) {
2249 			off_t i, n;
2250 			int c;
2251 
2252 			n = restart_point;
2253 			i = 0;
2254 			while (i++ < n) {
2255 				if ((c=getc(fin)) == EOF) {
2256 					perror_reply(550, name);
2257 					goto done;
2258 				}
2259 				if (c == '\n')
2260 					i++;
2261 			}
2262 		} else if (lseek(fileno(fin), restart_point, L_SET) < 0) {
2263 			perror_reply(550, name);
2264 			goto done;
2265 		}
2266 	}
2267 	dout = dataconn(name, st.st_size, "w");
2268 	if (dout == NULL) {
2269 		goto done;
2270 	}
2271 	time(&time_start);
2272 	send_err = send_data(fin, dout, st.st_blksize, st.st_size,
2273 		  restart_point == 0 && cmd == 0 && S_ISREG(st.st_mode));
2274 	time(&time_end);
2275 
2276 #ifdef USE_SSL
2277 	if (ssl_data_active_flag && (ssl_data_con != NULL)) {
2278 		if (SSL_shutdown(ssl_data_con) == 0) {
2279 		    switch (SSL_get_shutdown(ssl_data_con)) {
2280 		    case SSL_SENT_SHUTDOWN:
2281 			SSL_get_shutdown(ssl_data_con);
2282 			break;
2283 		    default:
2284 			break;
2285 		    }
2286 		}
2287 		SSL_free(ssl_data_con);
2288 		ssl_data_active_flag = 0;
2289 		ssl_data_con = NULL;
2290 	}
2291 #endif /* USE_SSL */
2292 
2293 	(void) fclose(dout);
2294 	data = -1;
2295 	pdata = -1;
2296 done:
2297 	if (cmd == 0) {
2298 		logxfer("get", name, st.st_size, time_start, time_end, 1,
2299 		    send_err);
2300 	}
2301 	(*closefunc)(fin);
2302 }
2303 
2304 void
store(char * name,char * mode,int unique)2305 store(char *name, char *mode, int unique)
2306 {
2307 	int fd;
2308 	FILE *fout, *din;
2309 	struct stat st;
2310 	int (*closefunc)(FILE *);
2311 	time_t time_start, time_end;
2312 	int rec_err = -1;
2313 
2314 	/* Set the default values */
2315 	time(&time_start);
2316 	time_end = time_start;
2317 
2318 	if (*mode == 'a') {		/* APPE */
2319 		if (unique) {
2320 			/* Programming error */
2321 			syslog(LOG_ERR, "Internal: unique flag to APPE");
2322 			unique = 0;
2323 		}
2324 		if (guest && noguestmod) {
2325 			reply(550, "Appending to existing file denied.");
2326 			goto err;
2327 		}
2328 		restart_point = 0;	/* not affected by preceding REST */
2329 	}
2330 	if (unique)			/* STOU overrides REST */
2331 		restart_point = 0;
2332 	if (guest && noguestmod) {
2333 		if (restart_point) {	/* guest STOR w/REST */
2334 			reply(550, "Modifying existing file denied.");
2335 			goto err;
2336 		} else			/* treat guest STOR as STOU */
2337 			unique = 1;
2338 	}
2339 
2340 	if (restart_point)
2341 		mode = "r+";	/* so ASCII manual seek can work */
2342 	if (unique) {
2343 		if ((fd = guniquefd(name, &name)) < 0)
2344 			goto err;
2345 		fout = fdopen(fd, mode);
2346 	} else
2347 		fout = fopen(name, mode);
2348 	closefunc = fclose;
2349 	if (fout == NULL) {
2350 		perror_reply(553, name);
2351 		goto err;
2352 	}
2353 	byte_count = -1;
2354 	if (restart_point) {
2355 		if (type == TYPE_A) {
2356 			off_t i, n;
2357 			int c;
2358 
2359 			n = restart_point;
2360 			i = 0;
2361 			while (i++ < n) {
2362 				if ((c=getc(fout)) == EOF) {
2363 					perror_reply(550, name);
2364 					goto done;
2365 				}
2366 				if (c == '\n')
2367 					i++;
2368 			}
2369 			/*
2370 			 * We must do this seek to "current" position
2371 			 * because we are changing from reading to
2372 			 * writing.
2373 			 */
2374 			if (fseeko(fout, 0, SEEK_CUR) < 0) {
2375 				perror_reply(550, name);
2376 				goto done;
2377 			}
2378 		} else if (lseek(fileno(fout), restart_point, L_SET) < 0) {
2379 			perror_reply(550, name);
2380 			goto done;
2381 		}
2382 	}
2383 	din = dataconn(name, -1, "r");
2384 	if (din == NULL) {
2385 		goto done;
2386 	}
2387 
2388 	time(&time_start);
2389 	rec_err = receive_data(din, fout);
2390 	time(&time_end);
2391 
2392 	if (rec_err == 0) {
2393 		if (unique)
2394 			reply(226, "Transfer complete (unique file name:%s).",
2395 			    name);
2396 		else
2397 			reply(226, "Transfer complete.");
2398 	}
2399 
2400 #ifdef USE_SSL
2401 	if (ssl_data_active_flag && (ssl_data_con != NULL)) {
2402 		if (SSL_shutdown(ssl_data_con) == 0) {
2403 		    switch (SSL_get_shutdown(ssl_data_con)) {
2404 		    case SSL_SENT_SHUTDOWN:
2405 			SSL_get_shutdown(ssl_data_con);
2406 			break;
2407 		    default:
2408 			break;
2409 		    }
2410 		}
2411 		SSL_free(ssl_data_con);
2412 		ssl_data_active_flag = 0;
2413 		ssl_data_con = NULL;
2414 	}
2415 #endif /* USE_SSL */
2416 
2417 	(void) fclose(din);
2418 	data = -1;
2419 	pdata = -1;
2420 done:
2421 	if (fstat(fileno(fout), &st) < 0) { /* Unexpected error... */
2422 		char wd[MAXPATHLEN + 1];
2423 		if (getcwd(wd, sizeof(wd) - 1) == NULL)
2424 			snprintf(wd, sizeof(wd), "%s", strerror(errno));
2425 		syslog(LOG_WARNING,
2426 		    "can't fstat the received file '%s' (wd: '%s')", name, wd);
2427 		st.st_size = 0;
2428 	}
2429 	logxfer(*mode == 'a' ? "append" : "put", name, st.st_size, time_start,
2430 	    time_end, 0, rec_err);
2431 	(*closefunc)(fout);
2432 	return;
2433 err:
2434 	LOGCMD(*mode == 'a' ? "append" : "put" , name);
2435 	return;
2436 }
2437 
2438 static FILE *
getdatasock(char * mode)2439 getdatasock(char *mode)
2440 {
2441 	int on = 1, s, t, tries;
2442 
2443 	if (data >= 0)
2444 		return (fdopen(data, mode));
2445 #ifdef BSDORIG_BIND
2446 	(void) seteuid(0);
2447 #endif
2448 
2449 	s = socket(data_dest.su_family, SOCK_STREAM, 0);
2450 	if (s < 0)
2451 		goto bad;
2452 	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
2453 		syslog(LOG_WARNING, "data setsockopt (SO_REUSEADDR): %m");
2454 	/* anchor socket to avoid multi-homing problems */
2455 	data_source = ctrl_addr;
2456 	data_source.su_port = htons(dataport);
2457 #ifndef BSDORIG_BIND
2458 	(void) seteuid(0);
2459 #endif
2460 	for (tries = 1; ; tries++) {
2461 		/*
2462 		 * We should loop here since it's possible that
2463 		 * another ftpd instance has passed this point and is
2464 		 * trying to open a data connection in active mode now.
2465 		 * Until the other connection is opened, we'll be getting
2466 		 * EADDRINUSE because no SOCK_STREAM sockets in the system
2467 		 * can share both local and remote addresses, localIP:20
2468 		 * and *:* in this case.
2469 		 */
2470 		if (bind(s, (struct sockaddr *)&data_source,
2471 #ifdef LINUX /* Linux port */
2472 		    SU_LEN(data_source)
2473 #else /* BSD source */
2474 		    data_source.su_len
2475 #endif /* BSD source */
2476 		    ) >= 0)
2477 			break;
2478 		if (errno != EADDRINUSE || tries > 10)
2479 			goto bad;
2480 		sleep(tries);
2481 	}
2482 	(void) seteuid(pw->pw_uid);
2483 #ifdef IP_TOS
2484 	if (data_source.su_family == AF_INET)
2485       {
2486 	on = IPTOS_THROUGHPUT;
2487 	if (setsockopt(s, IPPROTO_IP, IP_TOS, &on, sizeof(int)) < 0)
2488 		syslog(LOG_WARNING, "data setsockopt (IP_TOS): %m");
2489       }
2490 #endif
2491 #ifdef TCP_NOPUSH
2492 	/*
2493 	 * Turn off push flag to keep sender TCP from sending short packets
2494 	 * at the boundaries of each write().  Should probably do a SO_SNDBUF
2495 	 * to set the send buffer size as well, but that may not be desirable
2496 	 * in heavy-load situations.
2497 	 */
2498 	on = 1;
2499 	if (setsockopt(s, IPPROTO_TCP, TCP_NOPUSH, &on, sizeof on) < 0)
2500 		syslog(LOG_WARNING, "data setsockopt (TCP_NOPUSH): %m");
2501 #endif
2502 #ifdef SO_SNDBUF
2503 	on = 65536;
2504 	if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &on, sizeof on) < 0)
2505 		syslog(LOG_WARNING, "data setsockopt (SO_SNDBUF): %m");
2506 #endif
2507 
2508 	return (fdopen(s, mode));
2509 bad:
2510 	/* Return the real value of errno (close may change it) */
2511 	t = errno;
2512 	(void) seteuid(pw->pw_uid);
2513 	(void) close(s);
2514 	errno = t;
2515 	return (NULL);
2516 }
2517 
2518 static FILE *
dataconn(char * name,off_t size,char * mode)2519 dataconn(char *name, off_t size, char *mode)
2520 {
2521 	char sizebuf[32];
2522 	FILE *file;
2523 	int retry = 0, tos, conerrno;
2524 #ifdef USE_SSL
2525 	char *ssl_version;
2526 	int ssl_bits;
2527 	SSL_CIPHER *ssl_cipher;
2528 	X509 *x509_ssl_data_con, *x509_ssl_con;
2529 #endif /* USE_SSL */
2530 
2531 	file_size = size;
2532 	byte_count = 0;
2533 	if (size != -1)
2534 		(void) snprintf(sizebuf, sizeof(sizebuf),
2535 				" (%jd bytes)", (intmax_t)size);
2536 	else
2537 		*sizebuf = '\0';
2538 	if (pdata >= 0) {
2539 		union sockunion from;
2540 		int flags;
2541 		int s, fromlen =
2542 #ifdef LINUX /* Linux port */
2543 		SU_LEN(ctrl_addr);
2544 #else /* BSD source */
2545 		ctrl_addr.su_len;
2546 #endif /* BSD source */
2547 		struct timeval timeout;
2548 		fd_set set;
2549 
2550 		FD_ZERO(&set);
2551 		FD_SET(pdata, &set);
2552 
2553 		timeout.tv_usec = 0;
2554 		timeout.tv_sec = 120;
2555 
2556 		/*
2557 		 * Granted a socket is in the blocking I/O mode,
2558 		 * accept() will block after a successful select()
2559 		 * if the selected connection dies in between.
2560 		 * Therefore set the non-blocking I/O flag here.
2561 		 */
2562 		if ((flags = fcntl(pdata, F_GETFL, 0)) == -1 ||
2563 		    fcntl(pdata, F_SETFL, flags | O_NONBLOCK) == -1)
2564 			goto pdata_err;
2565 		if (select(pdata+1, &set, NULL, NULL, &timeout) <= 0 ||
2566 		    (s = accept(pdata, (struct sockaddr *) &from, &fromlen)) < 0)
2567 			goto pdata_err;
2568 		(void) close(pdata);
2569 		pdata = s;
2570 		/*
2571 		 * Unset the inherited non-blocking I/O flag
2572 		 * on the child socket so stdio can work on it.
2573 		 */
2574 		if ((flags = fcntl(pdata, F_GETFL, 0)) == -1 ||
2575 		    fcntl(pdata, F_SETFL, flags & ~O_NONBLOCK) == -1)
2576 			goto pdata_err;
2577 #ifdef IP_TOS
2578 		if (from.su_family == AF_INET)
2579 	      {
2580 		tos = IPTOS_THROUGHPUT;
2581 		if (setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof(int)) < 0)
2582 			syslog(LOG_WARNING, "pdata setsockopt (IP_TOS): %m");
2583 	      }
2584 #endif
2585 
2586 #ifdef USE_SSL
2587 		/*
2588 		 * Time to negotiate SSL on the data connection...
2589 		 * Do this via SSL_accept (as we are still the server
2590 		 * even though things are started around the other way).
2591 		 */
2592 		ssl_data_active_flag = 0;
2593 		if (ssl_active_flag && ssl_encrypt_data) {
2594 		    /* Do SSL */
2595 
2596 		    reply(150, "Opening %s mode SSL data connection for '%s'%s.",
2597 			 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
2598 
2599 		    if (ssl_data_con != NULL) {
2600 			SSL_free(ssl_data_con);
2601 			ssl_data_con = NULL;
2602 		    }
2603 
2604 		    ssl_data_con = (SSL *)SSL_new(ssl_ctx);
2605 		    SSL_set_accept_state(ssl_data_con);
2606 		    SSL_set_fd(ssl_data_con, pdata);
2607 
2608 		    if (ssl_debug_flag) {
2609 			ssl_log_msgn(bio_err, "Cached sessions: %d",
2610 			    SSL_CTX_sess_number(ssl_ctx));
2611 			ssl_log_msgn(bio_err,
2612 			    "===>START SSL_accept on passive mode DATA connection");
2613 		    }
2614 
2615 		    if (SSL_accept(ssl_data_con) <= 0) {
2616 			char errbuf[BUFSIZ];
2617 			snprintf(errbuf, sizeof(errbuf),
2618 				"SSL_accept DATA connection error %s.",
2619 				ERR_reason_error_string(ERR_get_error()));
2620 			perror_reply(425, errbuf);
2621 
2622 			/* Drop an established connection. */
2623 			close(pdata);
2624 			pdata = -1;
2625 
2626 			return NULL;
2627 		    } else {
2628 			if (ssl_debug_flag) {
2629 			    ssl_version = SSL_get_cipher_version(ssl_data_con);
2630 			    ssl_cipher = SSL_get_current_cipher(ssl_data_con);
2631 			    SSL_CIPHER_get_bits(ssl_cipher, &ssl_bits);
2632 			    ssl_log_msgn(bio_err,
2633 				"[DATA conn: %s, cipher %s, %d bits]",
2634 				ssl_version, SSL_CIPHER_get_name(ssl_cipher),
2635 				ssl_bits);
2636 			    ssl_log_msgn(bio_err,
2637 				"[DATA conn: session reused: %s]",
2638 				SSL_session_reused(ssl_data_con) ? "yes" : "no");
2639 			}
2640 
2641 			/* Get client certificates of control and data
2642 			 * connections. */
2643 			x509_ssl_con = SSL_get_peer_certificate(ssl_con);
2644 			x509_ssl_data_con = SSL_get_peer_certificate(ssl_data_con);
2645 
2646 			/*
2647 			 * Check the certificates if the client certificate
2648 			 * is presented for the control connection.
2649 			 */
2650 			switch (ssl_X509_cmp(x509_ssl_con, x509_ssl_data_con)) {
2651 			    char errbuf[BUFSIZ];
2652 			case -3:
2653 			    snprintf(errbuf, sizeof(errbuf),
2654 				"Client did not present a certificate for data connection.");
2655 			    reply(425, "%s", errbuf);
2656 
2657 			    /* Drop an established TLS/SSL connection. */
2658 			    SSL_free(ssl_data_con);
2659 			    ssl_data_con = NULL;
2660 			    close(pdata);
2661 			    pdata = -1;
2662 
2663 			    return NULL;
2664 			case 0:
2665 			    snprintf(errbuf, sizeof(errbuf),
2666 				"Client certificates for control and data connections are different.");
2667 			    reply(425, "%s", errbuf);
2668 
2669 			    /* Drop an established TLS/SSL connection. */
2670 			    SSL_free(ssl_data_con);
2671 			    ssl_data_con = NULL;
2672 			    close(pdata);
2673 			    pdata = -1;
2674 
2675 			    return NULL;
2676 			default:
2677 			    break;
2678 			}
2679 
2680 			X509_free(x509_ssl_con);
2681 			X509_free(x509_ssl_data_con);
2682 
2683 			ssl_data_active_flag = 1;
2684 		    }
2685 
2686 		    if (ssl_debug_flag)
2687 			ssl_log_msgn(bio_err,
2688 			"===>DONE SSL_accept on passive mode DATA connection");
2689 		} else {
2690 		    reply(150, "Opening %s mode data connection for '%s'%s.",
2691 			 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
2692 		}
2693 #else /* !USE_SSL */
2694 		reply(150, "Opening %s mode data connection for '%s'%s.",
2695 		     type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
2696 #endif /* USE_SSL */
2697 		return (fdopen(pdata, mode));
2698 pdata_err:
2699 		reply(425, "Can't open data connection.");
2700 		(void) close(pdata);
2701 		pdata = -1;
2702 		return (NULL);
2703 	}
2704 	if (data >= 0) {
2705 		reply(125, "Using existing data connection for '%s'%s.",
2706 		    name, sizebuf);
2707 		usedefault = 1;
2708 		return (fdopen(data, mode));
2709 	}
2710 	if (usedefault)
2711 		data_dest = his_addr;
2712 	usedefault = 1;
2713 	do {
2714 		file = getdatasock(mode);
2715 		if (file == NULL) {
2716 			char hostbuf[NI_MAXHOST], portbuf[NI_MAXSERV];
2717 
2718 			if (getnameinfo((struct sockaddr *)&data_source,
2719 #ifdef LINUX /* Linux port */
2720 				SU_LEN(data_source),
2721 #else /* BSD source */
2722 				data_source.su_len,
2723 #endif /* BSD source */
2724 				hostbuf, sizeof(hostbuf) - 1,
2725 				portbuf, sizeof(portbuf) - 1,
2726 				NI_NUMERICHOST|NI_NUMERICSERV))
2727 					*hostbuf = *portbuf = 0;
2728 			hostbuf[sizeof(hostbuf) - 1] = 0;
2729 			portbuf[sizeof(portbuf) - 1] = 0;
2730 			reply(425, "Can't create data socket (%s,%s): %s.",
2731 				hostbuf, portbuf, strerror(errno));
2732 			return (NULL);
2733 		}
2734 		data = fileno(file);
2735 		conerrno = 0;
2736 		if (connect(data, (struct sockaddr *)&data_dest,
2737 #ifdef LINUX /* Linux port */
2738 		    SU_LEN(data_dest)
2739 #else /* BSD source */
2740 		    data_dest.su_len
2741 #endif /* BSD source */
2742 		    ) == 0)
2743 			break;
2744 		conerrno = errno;
2745 		(void) fclose(file);
2746 		data = -1;
2747 		if (conerrno == EADDRINUSE) {
2748 			sleep(swaitint);
2749 			retry += swaitint;
2750 		} else {
2751 			break;
2752 		}
2753 	} while (retry <= swaitmax);
2754 	if (conerrno != 0) {
2755 		reply(425, "Can't build data connection: %s.",
2756 			   strerror(conerrno));
2757 		return (NULL);
2758 	}
2759 #ifdef USE_SSL
2760 	/*
2761 	 * Time to negotiate SSL on the data connection...
2762 	 * Do this via SSL_accept (as we are still the server
2763 	 * even though things are started around the other way).
2764 	 */
2765 	ssl_data_active_flag = 0;
2766 	if (ssl_active_flag && ssl_encrypt_data) {
2767 	    /* Do SSL */
2768 
2769 	    reply(150, "Opening %s mode SSL data connection for '%s'%s.",
2770 		 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
2771 
2772 	    if (ssl_data_con != NULL) {
2773 		SSL_free(ssl_data_con);
2774 		ssl_data_con = NULL;
2775 	    }
2776 
2777 	    ssl_data_con = (SSL *)SSL_new(ssl_ctx);
2778 	    SSL_set_accept_state(ssl_data_con);
2779 	    SSL_set_fd(ssl_data_con, data);
2780 
2781 	    if (ssl_debug_flag) {
2782 		ssl_log_msgn(bio_err, "Cached sessions: %d",
2783 			    SSL_CTX_sess_number(ssl_ctx));
2784 		ssl_log_msgn(bio_err, "===>START SSL_accept on DATA connection");
2785 	    }
2786 
2787 	    if (SSL_accept(ssl_data_con) <= 0) {
2788 		char errbuf[BUFSIZ];
2789 
2790 		snprintf(errbuf, sizeof(errbuf),
2791 			"SSL_accept DATA connection error %s.",
2792 			ERR_reason_error_string(ERR_get_error()));
2793 		perror_reply(425, errbuf);
2794 
2795 		/* Drop an established connection. */
2796 		fclose(file);
2797 		data = -1;
2798 
2799 		return NULL;
2800 	    } else {
2801 		if (ssl_debug_flag) {
2802 		    ssl_version = SSL_get_cipher_version(ssl_data_con);
2803 		    ssl_cipher = SSL_get_current_cipher(ssl_data_con);
2804 		    SSL_CIPHER_get_bits(ssl_cipher, &ssl_bits);
2805 		    ssl_log_msgn(bio_err, "[DATA conn: %s, cipher %s, %d bits]",
2806 				ssl_version, SSL_CIPHER_get_name(ssl_cipher),
2807 				ssl_bits);
2808 		    ssl_log_msgn(bio_err, "[DATA conn: session reused: %s]",
2809 				SSL_session_reused(ssl_data_con) ? "yes" : "no");
2810 		}
2811 
2812 		/* Get client certificates of control and data connections. */
2813 		x509_ssl_con=SSL_get_peer_certificate(ssl_con);
2814 		x509_ssl_data_con=SSL_get_peer_certificate(ssl_data_con);
2815 
2816 		/*
2817 		 * Check the certificates if the client certificate
2818 		 * is presented for the control connection.
2819 		 */
2820 		switch (ssl_X509_cmp(x509_ssl_con, x509_ssl_data_con)) {
2821 		    char errbuf[BUFSIZ];
2822 		case -3:
2823 		    snprintf(errbuf, sizeof(errbuf),
2824 			"Client did not present a certificate for data connection.");
2825 		    reply(425, "%s", errbuf);
2826 
2827 		    /* Drop an established TLS/SSL connection. */
2828 		    SSL_free(ssl_data_con);
2829 		    ssl_data_con = NULL;
2830     		    fclose(file);
2831 		    data = -1;
2832 
2833 		    return NULL;
2834 		case  0:
2835 		    snprintf(errbuf, sizeof(errbuf),
2836 			"Client certificates for control and data connections are different.");
2837 		    reply(425, "%s", errbuf);
2838 
2839 		    /* Drop an established TLS/SSL connection. */
2840 		    SSL_free(ssl_data_con);
2841 		    ssl_data_con = NULL;
2842 		    fclose(file);
2843 		    data = -1;
2844 
2845 		    return NULL;
2846 		default:
2847 		    break;
2848 		}
2849 
2850 		X509_free(x509_ssl_con);
2851 		X509_free(x509_ssl_data_con);
2852 
2853 		ssl_data_active_flag = 1;
2854 	    }
2855 
2856 	    if (ssl_debug_flag)
2857 		ssl_log_msgn(bio_err, "===>DONE SSL_accept on DATA connection");
2858 
2859 	} else {
2860 	    reply(150, "Opening %s mode data connection for '%s'%s.",
2861 		 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
2862 	}
2863 #else /* !USE_SSL */
2864 	reply(150, "Opening %s mode data connection for '%s'%s.",
2865 	     type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
2866 #endif /* USE_SSL */
2867 	return (file);
2868 }
2869 
2870 /*
2871  * Tranfer the contents of "instr" to "outstr" peer using the appropriate
2872  * encapsulation of the data subject to Mode, Structure, and Type.
2873  *
2874  * NB: Form isn't handled.
2875  */
2876 static int
send_data(FILE * instr,FILE * outstr,size_t blksize,off_t filesize,int isreg)2877 send_data(FILE *instr, FILE *outstr, size_t blksize, off_t filesize, int isreg)
2878 {
2879 	int c, cp, filefd, netfd;
2880 	char *buf, *bp;
2881 	off_t cnt = 0, len;
2882 
2883 	transflag++;
2884 	switch (type) {
2885 
2886 	case TYPE_A:
2887 		cp = '\0';
2888 		while ((c = getc(instr)) != EOF) {
2889 			if (recvurg)
2890 				if (myoob())
2891 					goto got_oob;
2892 			byte_count++;
2893  			if (c == '\n' && cp != '\r') {
2894 				if (ferror(outstr))
2895 					goto data_err;
2896 				(void) DATAPUTC('\r', outstr);
2897 			}
2898 			(void) DATAPUTC(c, outstr);
2899  			cp = c;
2900 		}
2901 		if (recvurg)
2902 			if (myoob())
2903 				goto got_oob;
2904 		DATAFLUSH(outstr);
2905 		transflag = 0;
2906 		if (ferror(instr))
2907 			goto file_err;
2908 		if (ferror(outstr))
2909 			goto data_err;
2910 		reply(226, "Transfer complete.");
2911 		return (0);
2912 
2913 	case TYPE_I:
2914 	case TYPE_L:
2915 		/*
2916 		 * isreg is only set if we are not doing restart and we
2917 		 * are sending a regular file
2918 		 */
2919 		netfd = fileno(outstr);
2920 		filefd = fileno(instr);
2921 
2922 		if (isreg) {
2923 			int trans_complete = 1;	/* "0" if we hit the EOF
2924 						 * prematurely */
2925 			off_t offset;
2926 #ifdef USE_SENDFILE
2927 			int err;
2928 #endif /* USE_SENDFILE */
2929 
2930 			cnt = offset = 0;
2931 #ifdef USE_SSL
2932 			if (ssl_data_active_flag) {
2933 			    if (filesize < (off_t)16 * 1024 * 1024) {
2934 				buf = mmap(0, filesize, PROT_READ, MAP_SHARED,
2935 				    filefd, (off_t)0);
2936 				if (buf == MAP_FAILED) {
2937 					syslog(LOG_WARNING, "mmap(%lu): %m",
2938 					    (unsigned long)filesize);
2939 					goto oldway;
2940 				}
2941 
2942 				bp = buf;
2943 				len = filesize;
2944 
2945 				do {
2946 				    cnt = ssl_write(ssl_data_con, bp, len);
2947 				    len -= cnt;
2948 				    bp += cnt;
2949 				    if (cnt > 0) byte_count += cnt;
2950 				    if (recvurg)
2951 					    if (myoob()) {
2952 						munmap(buf, (size_t)filesize);
2953 						goto got_oob;
2954 					    }
2955 				} while(cnt > 0 && len > 0);
2956 
2957 				munmap(buf, (size_t)filesize);
2958 				if (cnt < 0)
2959 					goto data_err;
2960 			    } else
2961 				goto oldway;
2962 			} else
2963 #endif /* USE_SSL */
2964 #ifdef USE_SENDFILE
2965 			while (filesize > 0) {
2966 #ifdef LINUX /* Linux port */
2967 				err = sendfile(filefd, netfd, &offset, filesize);
2968 				if (err >= 0)
2969 					cnt = err;
2970 				else
2971 					cnt = 0;
2972 #else /* BSD source */
2973 				err = sendfile(filefd, netfd, offset, 0,
2974 					       NULL, &cnt, 0);
2975 #endif /* BSD source */
2976 				/*
2977 				 * Calculate byte_count before OOB processing.
2978 				 * It can be used in myoob() later.
2979 				 */
2980 				byte_count += cnt;
2981 				if (recvurg)
2982 					if (myoob())
2983 						goto got_oob;
2984 				offset += cnt;
2985 				filesize -= cnt;
2986 
2987 				if (err == -1) {
2988 #ifndef LINUX /* BSD source */
2989 					if (errno == EAGAIN || errno == EINTR)
2990 						continue;
2991 #endif /* BSD source */
2992 					if (cnt == 0 && offset == 0)
2993 						goto oldway;
2994 
2995 					goto data_err;
2996 				}
2997 
2998 				/*
2999 				 * We hit the EOF prematurely.
3000 				 * Perhaps the file was externally truncated.
3001 				 */
3002 				if (cnt == 0) {
3003 					trans_complete = 0;
3004 					break;
3005 				}
3006 			}
3007 #else /* !USE_SENDFILE */
3008 			if (filesize < (off_t)16 * 1024 * 1024) {
3009 				buf = mmap(0, filesize, PROT_READ, MAP_SHARED,
3010 				    filefd, (off_t)0);
3011 				if (buf == MAP_FAILED) {
3012 					syslog(LOG_WARNING, "mmap(%lu): %m",
3013 					    (unsigned long)filesize);
3014 					goto oldway;
3015 				}
3016 				bp = buf;
3017 				len = filesize;
3018 
3019 				do {
3020 					cnt = write(netfd, bp, len);
3021 					len -= cnt;
3022 					bp += cnt;
3023 					if (cnt > 0) byte_count += cnt;
3024 					if (recvurg)
3025 						if (myoob()) {
3026 						    munmap(buf, (size_t)filesize);
3027 						    goto got_oob;
3028 						}
3029 				} while(cnt > 0 && len > 0);
3030 
3031 				munmap(buf, (size_t)filesize);
3032 				if (cnt < 0)
3033 					goto data_err;
3034 			} else
3035 				goto oldway;
3036 #endif /* USE_SENDFILE */
3037 			transflag = 0;
3038 			reply(226, "%s", trans_complete ?
3039 			    "Transfer complete." :
3040 			    "Transfer finished due to premature end of file.");
3041 			return (0);
3042 		}
3043 
3044 oldway:
3045 		if ((buf = malloc(blksize)) == NULL) {
3046 			transflag = 0;
3047 			reply(451, "Ran out of memory.");
3048 			return (-1);
3049 		}
3050 
3051 #ifdef USE_SSL
3052 		if (ssl_data_active_flag) {
3053 			while ((len = read(filefd, buf, blksize)) > 0 &&
3054 			    (cnt = ssl_write(ssl_data_con, buf, len)) == len) {
3055 				byte_count += cnt;
3056 				if (recvurg)
3057 					if (myoob()) {
3058 						free(buf);
3059 						goto got_oob;
3060 					}
3061 			}
3062 		} else
3063 #endif /* USE_SSL */
3064 		while ((len = read(filefd, buf, blksize)) > 0) {
3065 			bp = buf;
3066 			do {
3067 				cnt = write(netfd, bp, len);
3068 				len -= cnt;
3069 				bp += cnt;
3070 				if (cnt > 0) byte_count += cnt;
3071 				if (recvurg)
3072 					if (myoob()) {
3073 						free(buf);
3074 						goto got_oob;
3075 					}
3076 			} while (cnt > 0 && len > 0);
3077 		}
3078 		transflag = 0;
3079 		free(buf);
3080 		if (len < 0)
3081 		    goto file_err;
3082 		if (cnt < 0)
3083 		    goto data_err;
3084 		reply(226, "Transfer complete.");
3085 		return (0);
3086 	default:
3087 		transflag = 0;
3088 		reply(550, "Unimplemented TYPE %d in send_data.", type);
3089 		return (-1);
3090 	}
3091 
3092 data_err:
3093 	transflag = 0;
3094 	perror_reply(426, "Data connection");
3095 	return (-1);
3096 
3097 file_err:
3098 	transflag = 0;
3099 	perror_reply(551, "Error on input file");
3100 	return (-1);
3101 
3102 got_oob:
3103 	recvurg = 0;
3104 	transflag = 0;
3105 	DATAFLUSH(outstr);
3106 	return (-1);
3107 }
3108 
3109 /*
3110  * Transfer data from peer to "outstr" using the appropriate encapulation of
3111  * the data subject to Mode, Structure, and Type.
3112  *
3113  * N.B.: Form isn't handled.
3114  */
3115 static int
receive_data(FILE * instr,FILE * outstr)3116 receive_data(FILE *instr, FILE *outstr)
3117 {
3118 	int c;
3119 	int cnt, bare_lfs;
3120 	char buf[BUFSIZ];
3121 
3122 	transflag++;
3123 	bare_lfs = 0;
3124 
3125 	switch (type) {
3126 
3127 	case TYPE_I:
3128 	case TYPE_L:
3129 #ifdef USE_SSL
3130 		if (ssl_data_active_flag) {
3131 			while ((cnt = ssl_read(ssl_data_con, buf, sizeof buf)) > 0) {
3132 		        	if (write(fileno(outstr), buf, cnt) != cnt)
3133 			        	goto file_err;
3134 				byte_count += cnt;
3135 			}
3136 		} else
3137 #endif /* !USE_SSL */
3138 		while ((cnt = read(fileno(instr), buf, sizeof(buf))) > 0) {
3139 			if (recvurg)
3140 				if (myoob())
3141 					goto got_oob;
3142 			if (write(fileno(outstr), buf, cnt) != cnt)
3143 				goto file_err;
3144 			byte_count += cnt;
3145 		}
3146 		if (recvurg)
3147 			if (myoob())
3148 				goto got_oob;
3149 		if (cnt < 0)
3150 			goto data_err;
3151 		transflag = 0;
3152 		return (0);
3153 
3154 	case TYPE_E:
3155 		reply(553, "TYPE E not implemented.");
3156 		transflag = 0;
3157 		return (-1);
3158 
3159 	case TYPE_A:
3160 		while ((c = DATAGETC(instr)) != EOF) {
3161 			if (recvurg)
3162 				if (myoob())
3163 					goto got_oob;
3164 			byte_count++;
3165 			if (c == '\n')
3166 				bare_lfs++;
3167 			while (c == '\r') {
3168 				if (ferror(outstr))
3169 					goto data_err;
3170 				if ((c = DATAGETC(instr)) != '\n') {
3171 					(void) putc ('\r', outstr);
3172 					if (c == '\0' || c == EOF)
3173 						goto contin2;
3174 				}
3175 			}
3176 			(void) putc(c, outstr);
3177 	contin2:	;
3178 		}
3179 		if (recvurg)
3180 			if (myoob())
3181 				goto got_oob;
3182 		fflush(outstr);
3183 		if (ferror(instr))
3184 			goto data_err;
3185 		if (ferror(outstr))
3186 			goto file_err;
3187 		transflag = 0;
3188 		if (bare_lfs) {
3189 			lreply(226,
3190 		"WARNING! %d bare linefeeds received in ASCII mode.",
3191 			    bare_lfs);
3192 		(void)PRINTF("   File may not have transferred correctly.\r\n");
3193 		}
3194 		return (0);
3195 	default:
3196 		reply(550, "Unimplemented TYPE %d in receive_data.", type);
3197 		transflag = 0;
3198 		return (-1);
3199 	}
3200 
3201 data_err:
3202 	transflag = 0;
3203 	perror_reply(426, "Data connection");
3204 	return (-1);
3205 
3206 file_err:
3207 	transflag = 0;
3208 	perror_reply(452, "Error writing to file");
3209 	return (-1);
3210 
3211 got_oob:
3212 	recvurg = 0;
3213 	transflag = 0;
3214 	return (-1);
3215 }
3216 
3217 void
statfilecmd(char * filename)3218 statfilecmd(char *filename)
3219 {
3220 	FILE *fin;
3221 	int atstart;
3222 	int c, code;
3223 	char line[LINE_MAX];
3224 	struct stat st;
3225 
3226 	code = lstat(filename, &st) == 0 && S_ISDIR(st.st_mode) ? 212 : 213;
3227 	(void)snprintf(line, sizeof(line), _PATH_LS " -lgA %s", filename);
3228 	fin = ftpd_popen(line, "r");
3229 	lreply(code, "status of '%s':", filename);
3230 	atstart = 1;
3231 	while ((c = getc(fin)) != EOF) {
3232 		if (c == '\n') {
3233 			if (ferror(stdout)){
3234 				perror_reply(421, "Control connection");
3235 				(void) ftpd_pclose(fin);
3236 				dologout(1);
3237 				/* NOTREACHED */
3238 			}
3239 			if (ferror(fin)) {
3240 				perror_reply(551, filename);
3241 				(void) ftpd_pclose(fin);
3242 				return;
3243 			}
3244 			(void) PUTC('\r', stdout);
3245 		}
3246 		/*
3247 		 * RFC 959 says neutral text should be prepended before
3248 		 * a leading 3-digit number followed by whitespace, but
3249 		 * many ftp clients can be confused by any leading digits,
3250 		 * as a matter of fact.
3251 		 */
3252 		if (atstart && isdigit(c))
3253 			(void) PUTC(' ', stdout);
3254 		(void) PUTC(c, stdout);
3255 		atstart = (c == '\n');
3256 	}
3257 #ifdef USE_SSL
3258 	if (ssl_active_flag)
3259 		ssl_putc_flush(ssl_con);
3260 #endif /* USE_SSL */
3261 	(void) ftpd_pclose(fin);
3262 	reply(code, "End of status.");
3263 }
3264 
3265 void
statcmd(void)3266 statcmd(void)
3267 {
3268 	union sockunion *su;
3269 	u_char *a = NULL, *p = NULL;
3270 	char hname[NI_MAXHOST];
3271 	int ispassive;
3272 
3273 	if (hostinfo) {
3274 		lreply(211, "%s FTP server status:", hostname);
3275 		PRINTF("     %s\r\n", version);
3276 	} else
3277 		lreply(211, "FTP server status:");
3278 	PRINTF("     Connected to %s", remotehost);
3279 	if (!getnameinfo((struct sockaddr *)&his_addr,
3280 #ifdef LINUX /* Linux port */
3281 			 SU_LEN(his_addr),
3282 #else /* BSD source */
3283 			 his_addr.su_len,
3284 #endif /* BSD source */
3285 			 hname, sizeof(hname) - 1, NULL, 0, NI_NUMERICHOST)) {
3286 		hname[sizeof(hname) - 1] = 0;
3287 		if (strcmp(hname, remotehost) != 0)
3288 			PRINTF(" (%s)", hname);
3289 	}
3290 	PRINTF("\r\n");
3291 	if (logged_in) {
3292 		if (guest)
3293 			PRINTF("     Logged in anonymously\r\n");
3294 		else
3295 			PRINTF("     Logged in as %s\r\n", curname);
3296 	} else if (askpasswd)
3297 		PRINTF("     Waiting for password\r\n");
3298 	else
3299 		PRINTF("     Waiting for user name\r\n");
3300 #ifdef USE_SSL
3301 	PRINTF("     TLS/SSL protection of control connection: %s\r\n",
3302 		ssl_active_flag ? "ON" : "OFF");
3303 	PRINTF("     TLS/SSL protection of data connections: %s\r\n",
3304 		ssl_encrypt_data ? "ON" : "OFF");
3305 	PRINTF("     FTP-SSL compatibility mode: %s\r\n",
3306 		ssl_compat_flag ? "ON" : "OFF");
3307 #endif /*USE_SSL*/
3308 	PRINTF("     TYPE: %s", typenames[type]);
3309 	if (type == TYPE_A || type == TYPE_E)
3310 		PRINTF(", FORM: %s", formnames[form]);
3311 	if (type == TYPE_L)
3312 #if CHAR_BIT == 8
3313 		PRINTF(" %d", CHAR_BIT);
3314 #else
3315 		PRINTF(" %d", bytesize);	/* need definition! */
3316 #endif
3317 	PRINTF("; STRUcture: %s; transfer MODE: %s\r\n",
3318 	    strunames[stru], modenames[mode]);
3319 	if (data != -1)
3320 		PRINTF("     Data connection open\r\n");
3321 	else if (pdata != -1) {
3322 		ispassive = 1;
3323 		su = &pasv_addr;
3324 		goto printaddr;
3325 	} else if (usedefault == 0) {
3326 		ispassive = 0;
3327 		su = &data_dest;
3328 printaddr:
3329 #define UC(b) (((int) b) & 0xff)
3330 		if (epsvall) {
3331 			PRINTF("     EPSV only mode (EPSV ALL)\r\n");
3332 			goto epsvonly;
3333 		}
3334 
3335 		/* PORT/PASV */
3336 		if (su->su_family == AF_INET) {
3337 			a = (u_char *) &su->su_sin.sin_addr;
3338 			p = (u_char *) &su->su_sin.sin_port;
3339 			PRINTF("     %s (%d,%d,%d,%d,%d,%d)\r\n",
3340 				ispassive ? "PASV" : "PORT",
3341 				UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
3342 				UC(p[0]), UC(p[1]));
3343 		}
3344 
3345 		/* LPRT/LPSV */
3346 	    {
3347 		int alen = 0, af, i;
3348 
3349 		switch (su->su_family) {
3350 		case AF_INET:
3351 			a = (u_char *) &su->su_sin.sin_addr;
3352 			p = (u_char *) &su->su_sin.sin_port;
3353 			alen = sizeof(su->su_sin.sin_addr);
3354 			af = 4;
3355 			break;
3356 #ifdef INET6
3357 		case AF_INET6:
3358 			a = (u_char *) &su->su_sin6.sin6_addr;
3359 			p = (u_char *) &su->su_sin6.sin6_port;
3360 			alen = sizeof(su->su_sin6.sin6_addr);
3361 			af = 6;
3362 			break;
3363 #endif
3364 		default:
3365 			af = 0;
3366 			break;
3367 		}
3368 		if (af) {
3369 			PRINTF("     %s (%d,%d,", ispassive ? "LPSV" : "LPRT",
3370 				af, alen);
3371 			for (i = 0; i < alen; i++)
3372 				PRINTF("%d,", UC(a[i]));
3373 			PRINTF("%d,%d,%d)\r\n", 2, UC(p[0]), UC(p[1]));
3374 		}
3375 	    }
3376 
3377 epsvonly:;
3378 		/* EPRT/EPSV */
3379 	    {
3380 		int af;
3381 
3382 		switch (su->su_family) {
3383 		case AF_INET:
3384 			af = 1;
3385 			break;
3386 #ifdef INET6
3387 		case AF_INET6:
3388 			af = 2;
3389 			break;
3390 #endif
3391 		default:
3392 			af = 0;
3393 			break;
3394 		}
3395 		if (af) {
3396 			union sockunion tmp;
3397 
3398 			tmp = *su;
3399 #ifdef INET6
3400 			if (tmp.su_family == AF_INET6)
3401 				tmp.su_sin6.sin6_scope_id = 0;
3402 #endif
3403 			if (!getnameinfo((struct sockaddr *)&tmp,
3404 #ifdef LINUX /* Linux port */
3405 					SU_LEN(tmp),
3406 #else /* BSD source */
3407 					tmp.su_len,
3408 #endif /* BSD source */
3409 					hname, sizeof(hname) - 1, NULL, 0,
3410 					NI_NUMERICHOST)) {
3411 				hname[sizeof(hname) - 1] = 0;
3412 				PRINTF("     %s |%d|%s|%d|\r\n",
3413 					ispassive ? "EPSV" : "EPRT",
3414 					af, hname, htons(tmp.su_port));
3415 			}
3416 		}
3417 	    }
3418 #undef UC
3419 	} else
3420 		PRINTF("     No data connection\r\n");
3421 	reply(211, "End of status.");
3422 }
3423 
3424 void
fatalerror(char * s)3425 fatalerror(char *s)
3426 {
3427 
3428 	reply(451, "Error in server: %s", s);
3429 	reply(221, "Closing connection due to server error.");
3430 	dologout(0);
3431 	/* NOTREACHED */
3432 }
3433 
3434 void
reply(int n,const char * fmt,...)3435 reply(int n, const char *fmt, ...)
3436 {
3437 	va_list ap;
3438 #ifdef USE_SSL
3439 	/* the size seems to be enough for normal use */
3440 	char outputbuf[BUFSIZ + MAXPATHLEN + MAXHOSTNAMELEN];
3441 	size_t outputbuflen;
3442 #endif /* USE_SSL */
3443 
3444 #ifdef USE_SSL
3445 	snprintf(outputbuf, sizeof(outputbuf) - 2, "%d ", n);
3446 	va_start(ap, fmt);
3447 	outputbuflen = strlen(outputbuf);
3448 	vsnprintf(outputbuf + outputbuflen,
3449 		 sizeof(outputbuf) - outputbuflen - 2, fmt, ap);
3450 	va_end(ap);
3451 	strcat(outputbuf, "\r\n");
3452 
3453 	if (ssl_debug_flag)
3454 		ssl_log_msg(bio_err, "\n<--- %s", outputbuf);
3455 
3456 	if (ssl_active_flag) {
3457 		ssl_write(ssl_con, outputbuf, strlen(outputbuf));
3458 	} else {
3459 		printf("%s", outputbuf);
3460 		fflush(stdout);
3461 	}
3462 
3463 	if (ftpdebug)
3464 		syslog(LOG_DEBUG, "<--- %s ", outputbuf);
3465 #else /* !USE_SSL */
3466 	(void)printf("%d ", n);
3467 	va_start(ap, fmt);
3468 	(void)vprintf(fmt, ap);
3469 	va_end(ap);
3470 	(void)printf("\r\n");
3471 	(void)fflush(stdout);
3472 	if (ftpdebug) {
3473 		syslog(LOG_DEBUG, "<--- %d ", n);
3474 		va_start(ap, fmt);
3475 		vsyslog(LOG_DEBUG, fmt, ap);
3476 		va_end(ap);
3477 	}
3478 #endif /* USE_SSL */
3479 }
3480 
3481 void
lreply(int n,const char * fmt,...)3482 lreply(int n, const char *fmt, ...)
3483 {
3484 	va_list ap;
3485 #ifdef USE_SSL
3486 	/* the size seems to be enough for normal use */
3487 	char outputbuf[BUFSIZ + MAXPATHLEN + MAXHOSTNAMELEN];
3488 	size_t outputbuflen;
3489 #endif /* USE_SSL */
3490 
3491 #ifdef USE_SSL
3492 	snprintf(outputbuf, sizeof(outputbuf) - 2, "%d- ", n);
3493 	va_start(ap, fmt);
3494 	outputbuflen = strlen(outputbuf);
3495 	vsnprintf(outputbuf + outputbuflen,
3496 		 sizeof(outputbuf) - outputbuflen - 2, fmt, ap);
3497 	va_end(ap);
3498 	strcat(outputbuf, "\r\n");
3499 
3500 	if (ssl_debug_flag)
3501 		ssl_log_msg(bio_err, "\n<--- %s", outputbuf);
3502 
3503 	if (ssl_active_flag) {
3504 		ssl_write(ssl_con, outputbuf, strlen(outputbuf));
3505 	} else {
3506 		printf("%s", outputbuf);
3507 		fflush(stdout);
3508 	}
3509 
3510 	if (ftpdebug)
3511 		syslog(LOG_DEBUG, "<--- %s ", outputbuf);
3512 #else /* !USE_SSL */
3513 	(void)printf("%d- ", n);
3514 	va_start(ap, fmt);
3515 	(void)vprintf(fmt, ap);
3516 	va_end(ap);
3517 	(void)printf("\r\n");
3518 	(void)fflush(stdout);
3519 	if (ftpdebug) {
3520 		syslog(LOG_DEBUG, "<--- %d- ", n);
3521 		va_start(ap, fmt);
3522 		vsyslog(LOG_DEBUG, fmt, ap);
3523 		va_end(ap);
3524 	}
3525 #endif /* USE_SSL */
3526 }
3527 
3528 static void
ack(char * s)3529 ack(char *s)
3530 {
3531 
3532 	reply(250, "%s command successful.", s);
3533 }
3534 
3535 void
nack(char * s)3536 nack(char *s)
3537 {
3538 
3539 	reply(502, "%s command not implemented.", s);
3540 }
3541 
3542 /*
3543  * Return the "Syntax error" reply to the client.
3544  * arguments:
3545  *	s - the buffer which contains the FTP command.
3546  */
3547 void
synterr(char * s)3548 synterr(char *s)
3549 {
3550 	char *cp;
3551 
3552 	if ((cp = strchr(s,'\n')))
3553 		*cp = '\0';
3554 	reply(501, "%s: syntax error in arguments.", s);
3555 }
3556 
3557 /* ARGSUSED */
3558 void
yyerror(char * s)3559 yyerror(char *s)
3560 {
3561 	char *cp;
3562 
3563 	if ((cp = strchr(cbuf,'\n')))
3564 		*cp = '\0';
3565 	reply(500, "%s: command not understood.", cbuf);
3566 }
3567 
3568 void
delete(char * name)3569 delete(char *name)
3570 {
3571 	struct stat st;
3572 
3573 	LOGCMD("delete", name);
3574 	if (lstat(name, &st) < 0) {
3575 		perror_reply(550, name);
3576 		return;
3577 	}
3578 	if (S_ISDIR(st.st_mode)) {
3579 		if (rmdir(name) < 0) {
3580 			perror_reply(550, name);
3581 			return;
3582 		}
3583 		goto done;
3584 	}
3585 	if (guest && noguestmod) {
3586 		reply(550, "Operation not permitted.");
3587 		return;
3588 	}
3589 	if (unlink(name) < 0) {
3590 		perror_reply(550, name);
3591 		return;
3592 	}
3593 done:
3594 	ack("DELE");
3595 }
3596 
3597 void
cwd(char * path)3598 cwd(char *path)
3599 {
3600 
3601 	if (chdir(path) < 0)
3602 		perror_reply(550, path);
3603 	else
3604 		ack("CWD");
3605 }
3606 
3607 void
makedir(char * name)3608 makedir(char *name)
3609 {
3610 	char *s;
3611 
3612 	LOGCMD("mkdir", name);
3613 	if (guest && noguestmkd)
3614 		reply(550, "Operation not permitted.");
3615 	else if (mkdir(name, 0777) < 0)
3616 		perror_reply(550, name);
3617 	else {
3618 		if ((s = doublequote(name)) == NULL)
3619 			fatalerror("Ran out of memory.");
3620 		reply(257, "\"%s\" directory created.", s);
3621 		free(s);
3622 	}
3623 }
3624 
3625 void
removedir(char * name)3626 removedir(char *name)
3627 {
3628 
3629 	LOGCMD("rmdir", name);
3630 	if (rmdir(name) < 0)
3631 		perror_reply(550, name);
3632 	else
3633 		ack("RMD");
3634 }
3635 
3636 void
pwd(void)3637 pwd(void)
3638 {
3639 	char *s, path[MAXPATHLEN + 1];
3640 
3641 	if (getcwd(path, sizeof(path)) == NULL)
3642 		perror_reply(550, "Get current directory");
3643 	else {
3644 		if ((s = doublequote(path)) == NULL)
3645 			fatalerror("Ran out of memory.");
3646 		reply(257, "\"%s\" is current directory.", s);
3647 		free(s);
3648 	}
3649 }
3650 
3651 char *
renamefrom(char * name)3652 renamefrom(char *name)
3653 {
3654 	struct stat st;
3655 
3656 	if (guest && noguestmod) {
3657 		reply(550, "Operation not permitted.");
3658 		return (NULL);
3659 	}
3660 	if (lstat(name, &st) < 0) {
3661 		perror_reply(550, name);
3662 		return (NULL);
3663 	}
3664 	reply(350, "File exists, ready for destination name.");
3665 	return (name);
3666 }
3667 
3668 void
renamecmd(char * from,char * to)3669 renamecmd(char *from, char *to)
3670 {
3671 	struct stat st;
3672 
3673 	LOGCMD2("rename", from, to);
3674 
3675 	if (guest && (stat(to, &st) == 0)) {
3676 		reply(550, "%s: permission denied.", to);
3677 		return;
3678 	}
3679 
3680 	if (rename(from, to) < 0)
3681 		perror_reply(550, "rename");
3682 	else
3683 		ack("RNTO");
3684 }
3685 
3686 static void
dolog(struct sockaddr * who)3687 dolog(struct sockaddr *who)
3688 {
3689 	char who_name[NI_MAXHOST];
3690 
3691 	realhostname_sa(remotehost, sizeof(remotehost) - 1, who,
3692 #ifdef LINUX /* Linux port */
3693 	    SA_LEN(who));
3694 #else /* BSD source */
3695 	    who->sa_len);
3696 #endif /* BSD source */
3697 	remotehost[sizeof(remotehost) - 1] = 0;
3698 	if (getnameinfo(who,
3699 #ifdef LINUX /* Linux port */
3700 		    SA_LEN(who),
3701 #else /* BSD source */
3702 		    who->sa_len,
3703 #endif /* BSD source */
3704 		who_name, sizeof(who_name) - 1, NULL, 0, NI_NUMERICHOST))
3705 			*who_name = 0;
3706 	who_name[sizeof(who_name) - 1] = 0;
3707 
3708 #ifdef SETPROCTITLE
3709 #ifdef VIRTUAL_HOSTING
3710 	if (thishost != firsthost)
3711 		snprintf(proctitle, sizeof(proctitle), "%s: connected (to %s)",
3712 			 remotehost, hostname);
3713 	else
3714 #endif
3715 		snprintf(proctitle, sizeof(proctitle), "%s: connected",
3716 			 remotehost);
3717 	setproctitle("%s", proctitle);
3718 #endif /* SETPROCTITLE */
3719 
3720 	if (logging) {
3721 #ifdef VIRTUAL_HOSTING
3722 		if (thishost != firsthost)
3723 			syslog(LOG_INFO, "connection from %s (%s) to %s",
3724 			       remotehost, who_name, hostname);
3725 		else
3726 #endif
3727 			syslog(LOG_INFO, "connection from %s (%s)",
3728 			       remotehost, who_name);
3729 	}
3730 }
3731 
3732 /*
3733  * Record logout in wtmp file
3734  * and exit with supplied status.
3735  */
3736 void
dologout(int status)3737 dologout(int status)
3738 {
3739 	if (logged_in && dowtmp) {
3740 		(void) seteuid(0);
3741 		ftpd_logwtmp(ttyline, "", NULL);
3742 	}
3743 
3744 	if (logging)
3745 		syslog(LOG_INFO, "connection %s", recvlostconn ?
3746 		      "lost" : "closed");
3747 
3748 	/* beware of flushing buffers after a SIGPIPE */
3749 	_exit(status);
3750 }
3751 
3752 static void
sigurg(int signo)3753 sigurg(int signo)
3754 {
3755 	/* only process if transfer occurring */
3756 	if (!transflag)
3757 		return;
3758 
3759 	recvurg = 1;
3760 }
3761 
3762 static int
myoob(void)3763 myoob(void)
3764 {
3765 	char *cp;
3766 #ifdef USE_SSL /* "pseudo-OOB" with SSL */
3767 	fd_set mask;
3768 	struct timeval tv;
3769 #endif /*USE_SSL*/
3770 
3771 	/* only process if transfer occurring */
3772 	if (!transflag) {
3773 		recvurg = 0;
3774 		return 0;
3775 	}
3776 	cp = tmpline;
3777 #ifdef USE_SSL /* "pseudo-OOB" with SSL */
3778 	FD_ZERO(&mask);
3779 	FD_SET(fileno(stdin),&mask);
3780 	tv.tv_sec=0;
3781 	tv.tv_usec=0;
3782 	if (select(fileno(stdin)+1, &mask, NULL, NULL, &tv)) {
3783 #endif /*USE_SSL*/
3784 	if (get_line(cp, 7, stdin) == NULL) {
3785 		reply(221, "You could at least say goodbye.");
3786 		dologout(0);
3787 	}
3788 	upper(cp);
3789 	if (strcmp(cp, "ABOR\r\n") == 0) {
3790 		tmpline[0] = '\0';
3791 		reply(426, "Transfer aborted. Data connection closed.");
3792 		reply(226, "Abort successful.");
3793 
3794 		return 1;
3795 	}
3796 	if (strcmp(cp, "STAT\r\n") == 0) {
3797 		tmpline[0] = '\0';
3798 		if (file_size != -1)
3799 			reply(213, "Status: %jd of %jd bytes transferred.",
3800 				   (intmax_t)byte_count, (intmax_t)file_size);
3801 		else
3802 			reply(213, "Status: %jd bytes transferred.",
3803 				   (intmax_t)byte_count);
3804 	}
3805 #ifdef USE_SSL /* "pseudo-OOB" with SSL */
3806 	}
3807 #endif /*USE_SSL*/
3808 	recvurg = 0;
3809 	return 0;
3810 }
3811 
3812 /*
3813  * Note: a response of 425 is not mentioned as a possible response to
3814  *	the PASV command in RFC959. However, it has been blessed as
3815  *	a legitimate response by Jon Postel in a telephone conversation
3816  *	with Rick Adams on 25 Jan 89.
3817  */
3818 void
passive(void)3819 passive(void)
3820 {
3821 	int len, on;
3822 	char *p, *a;
3823 
3824 	if (pdata >= 0)		/* close old port if one set */
3825 		close(pdata);
3826 
3827 	pdata = socket(ctrl_addr.su_family, SOCK_STREAM, 0);
3828 	if (pdata < 0) {
3829 		perror_reply(425, "Can't open passive connection");
3830 		return;
3831 	}
3832 	on = 1;
3833 	if (setsockopt(pdata, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
3834 		syslog(LOG_WARNING, "pdata setsockopt (SO_REUSEADDR): %m");
3835 
3836 	(void) seteuid(0);
3837 
3838 #ifdef IP_PORTRANGE
3839 	if (ctrl_addr.su_family == AF_INET) {
3840 	    on = restricted_data_ports ? IP_PORTRANGE_HIGH
3841 				       : IP_PORTRANGE_DEFAULT;
3842 
3843 	    if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE,
3844 			    &on, sizeof(on)) < 0)
3845 		    goto pasv_error;
3846 	}
3847 #endif
3848 #ifdef IPV6_PORTRANGE
3849 	if (ctrl_addr.su_family == AF_INET6) {
3850 	    on = restricted_data_ports ? IPV6_PORTRANGE_HIGH
3851 				       : IPV6_PORTRANGE_DEFAULT;
3852 
3853 	    if (setsockopt(pdata, IPPROTO_IPV6, IPV6_PORTRANGE,
3854 			    &on, sizeof(on)) < 0)
3855 		    goto pasv_error;
3856 	}
3857 #endif
3858 
3859 	pasv_addr = ctrl_addr;
3860 	pasv_addr.su_port = 0;
3861 	if (bind(pdata, (struct sockaddr *)&pasv_addr,
3862 #ifdef LINUX /* Linux port */
3863 	SU_LEN(pasv_addr)
3864 #else /* BSD source */
3865 	pasv_addr.su_len
3866 #endif /* BSD source */
3867 	) < 0)
3868 		goto pasv_error;
3869 
3870 	(void) seteuid(pw->pw_uid);
3871 
3872 	len = sizeof(pasv_addr);
3873 	if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0)
3874 		goto pasv_error;
3875 	if (listen(pdata, 1) < 0)
3876 		goto pasv_error;
3877 	if (pasv_addr.su_family == AF_INET)
3878 		if (tun_pasvip_flag)
3879 			a = (char *) &tun_pasvip_addr.su_sin.sin_addr;
3880 		else
3881 			a = (char *) &pasv_addr.su_sin.sin_addr;
3882 #ifdef INET6
3883 	else if (pasv_addr.su_family == AF_INET6 &&
3884 		 IN6_IS_ADDR_V4MAPPED(&pasv_addr.su_sin6.sin6_addr))
3885 		if (tun_pasvip_flag)
3886 			a = (char *) &tun_pasvip_addr.su_sin.sin_addr;
3887 		else
3888 			a = (char *) &pasv_addr.su_sin6.sin6_addr.s6_addr[12];
3889 #endif
3890 	else
3891 		goto pasv_error;
3892 
3893 	p = (char *) &pasv_addr.su_port;
3894 
3895 #define UC(b) (((int) b) & 0xff)
3896 
3897 	reply(227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", UC(a[0]),
3898 		UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
3899 	return;
3900 
3901 pasv_error:
3902 	(void) seteuid(pw->pw_uid);
3903 	(void) close(pdata);
3904 	pdata = -1;
3905 	perror_reply(425, "Can't open passive connection");
3906 	return;
3907 }
3908 
3909 /*
3910  * Long Passive defined in RFC 1639.
3911  *     228 Entering Long Passive Mode
3912  *         (af, hal, h1, h2, h3,..., pal, p1, p2...)
3913  */
3914 
3915 void
long_passive(char * cmd,int pf)3916 long_passive(char *cmd, int pf)
3917 {
3918 	int len, on;
3919 	char *p, *a;
3920 
3921 	if (pdata >= 0)		/* close old port if one set */
3922 		close(pdata);
3923 
3924 	if (pf != PF_UNSPEC) {
3925 		if (ctrl_addr.su_family != pf) {
3926 			switch (ctrl_addr.su_family) {
3927 			case AF_INET:
3928 				pf = 1;
3929 				break;
3930 #ifdef INET6
3931 			case AF_INET6:
3932 				pf = 2;
3933 				break;
3934 #endif
3935 			default:
3936 				pf = 0;
3937 				break;
3938 			}
3939 			/*
3940 			 * XXX
3941 			 * only EPRT/EPSV ready clients will understand this
3942 			 */
3943 			if (strcmp(cmd, "EPSV") == 0 && pf) {
3944 				reply(522, "Network protocol mismatch, "
3945 					"use (%d)", pf);
3946 			} else
3947 				reply(501, "Network protocol mismatch."); /*XXX*/
3948 
3949 			return;
3950 		}
3951 	}
3952 
3953 	pdata = socket(ctrl_addr.su_family, SOCK_STREAM, 0);
3954 	if (pdata < 0) {
3955 		perror_reply(425, "Can't open passive connection");
3956 		return;
3957 	}
3958 	on = 1;
3959 	if (setsockopt(pdata, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
3960 		syslog(LOG_WARNING, "pdata setsockopt (SO_REUSEADDR): %m");
3961 
3962 	(void) seteuid(0);
3963 
3964 	pasv_addr = ctrl_addr;
3965 	pasv_addr.su_port = 0;
3966 	len =
3967 #ifdef LINUX /* Linux port */
3968 	SU_LEN(pasv_addr);
3969 #else /* BSD source */
3970 	pasv_addr.su_len;
3971 #endif /* BSD source */
3972 
3973 #ifdef IP_PORTRANGE
3974 	if (ctrl_addr.su_family == AF_INET) {
3975 	    on = restricted_data_ports ? IP_PORTRANGE_HIGH
3976 				       : IP_PORTRANGE_DEFAULT;
3977 
3978 	    if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE,
3979 			    &on, sizeof(on)) < 0)
3980 		    goto pasv_error;
3981 	}
3982 #endif
3983 #ifdef IPV6_PORTRANGE
3984 	if (ctrl_addr.su_family == AF_INET6) {
3985 	    on = restricted_data_ports ? IPV6_PORTRANGE_HIGH
3986 				       : IPV6_PORTRANGE_DEFAULT;
3987 
3988 	    if (setsockopt(pdata, IPPROTO_IPV6, IPV6_PORTRANGE,
3989 			    &on, sizeof(on)) < 0)
3990 		    goto pasv_error;
3991 	}
3992 #endif
3993 
3994 	if (bind(pdata, (struct sockaddr *)&pasv_addr, len) < 0)
3995 		goto pasv_error;
3996 
3997 	(void) seteuid(pw->pw_uid);
3998 
3999 	if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0)
4000 		goto pasv_error;
4001 	if (listen(pdata, 1) < 0)
4002 		goto pasv_error;
4003 
4004 #define UC(b) (((int) b) & 0xff)
4005 
4006 	if (strcmp(cmd, "LPSV") == 0) {
4007 		p = (char *)&pasv_addr.su_port;
4008 		switch (pasv_addr.su_family) {
4009 		case AF_INET:
4010 			if (tun_pasvip_flag)
4011 				a = (char *) &tun_pasvip_addr.su_sin.sin_addr;
4012 			else
4013 				a = (char *) &pasv_addr.su_sin.sin_addr;
4014 #ifdef INET6
4015 		v4_reply:
4016 #endif
4017 			reply(228,
4018 "Entering Long Passive Mode (%d,%d,%d,%d,%d,%d,%d,%d,%d)",
4019 			      4, 4, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
4020 			      2, UC(p[0]), UC(p[1]));
4021 			return;
4022 #ifdef INET6
4023 		case AF_INET6:
4024 			if (IN6_IS_ADDR_V4MAPPED(&pasv_addr.su_sin6.sin6_addr)) {
4025 				if (tun_pasvip_flag)
4026 					a = (char *) &tun_pasvip_addr.su_sin.sin_addr;
4027 				else
4028 					a = (char *) &pasv_addr.su_sin6.sin6_addr.s6_addr[12];
4029 				goto v4_reply;
4030 			}
4031 			a = (char *) &pasv_addr.su_sin6.sin6_addr;
4032 			reply(228,
4033 "Entering Long Passive Mode "
4034 "(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",
4035 			      6, 16, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
4036 			      UC(a[4]), UC(a[5]), UC(a[6]), UC(a[7]),
4037 			      UC(a[8]), UC(a[9]), UC(a[10]), UC(a[11]),
4038 			      UC(a[12]), UC(a[13]), UC(a[14]), UC(a[15]),
4039 			      2, UC(p[0]), UC(p[1]));
4040 			return;
4041 #endif
4042 		}
4043 	} else if (strcmp(cmd, "EPSV") == 0) {
4044 		switch (pasv_addr.su_family) {
4045 		case AF_INET:
4046 #ifdef INET6
4047 		case AF_INET6:
4048 #endif
4049 			reply(229, "Entering Extended Passive Mode (|||%d|)",
4050 				ntohs(pasv_addr.su_port));
4051 			return;
4052 		}
4053 	} else {
4054 		/* more proper error code? */
4055 	}
4056 
4057 pasv_error:
4058 	(void) seteuid(pw->pw_uid);
4059 	(void) close(pdata);
4060 	pdata = -1;
4061 	perror_reply(425, "Can't open passive connection");
4062 	return;
4063 }
4064 
4065 /*
4066  * Generate unique name for file with basename "local"
4067  * and open the file in order to avoid possible races.
4068  * Try "local" first, then "local.1", "local.2" etc, up to "local.99".
4069  * Return descriptor to the file, set "name" to its name.
4070  *
4071  * Generates failure reply on error.
4072  */
4073 static int
guniquefd(char * local,char ** name)4074 guniquefd(char *local, char **name)
4075 {
4076 	static char new[MAXPATHLEN];
4077 	struct stat st;
4078 	char *cp;
4079 	int count;
4080 	int fd;
4081 
4082 	cp = strrchr(local, '/');
4083 	if (cp)
4084 		*cp = '\0';
4085 	if (stat(cp ? local : ".", &st) < 0) {
4086 		perror_reply(553, cp ? local : ".");
4087 		return (-1);
4088 	}
4089 	if (cp) {
4090 		/*
4091 		 * Let not overwrite dirname with counter suffix.
4092 		 * -4 is for /nn\0
4093 		 * In this extreme case dot won't be put in front of suffix.
4094 		 */
4095 		if (strlen(local) > sizeof(new) - 4) {
4096 			reply(553, "Pathname too long.");
4097 			return (-1);
4098 		}
4099 		*cp = '/';
4100 	}
4101 	/* -4 is for the .nn<null> we put on the end below */
4102 	(void) snprintf(new, sizeof(new) - 4, "%s", local);
4103 	cp = new + strlen(new);
4104 	/*
4105 	 * Don't generate dotfile unless requested explicitly.
4106 	 * This covers the case when basename gets truncated off
4107 	 * by buffer size.
4108 	 */
4109 	if (cp > new && cp[-1] != '/')
4110 		*cp++ = '.';
4111 	for (count = 0; count < 100; count++) {
4112 		/* At count 0 try unmodified name */
4113 		if (count)
4114 			(void)sprintf(cp, "%d", count);
4115 		if ((fd = open(count ? new : local,
4116 		    O_RDWR | O_CREAT | O_EXCL, 0666)) >= 0) {
4117 			*name = count ? new : local;
4118 			return (fd);
4119 		}
4120 		if (errno != EEXIST) {
4121 			perror_reply(553, count ? new : local);
4122 			return (-1);
4123 		}
4124 	}
4125 	reply(452, "Unique file name cannot be created.");
4126 	return (-1);
4127 }
4128 
4129 /*
4130  * Format and send reply containing system error number.
4131  */
4132 void
perror_reply(int code,char * string)4133 perror_reply(int code, char *string)
4134 {
4135 
4136 	reply(code, "%s: %s.", string, strerror(errno));
4137 }
4138 
4139 static char *onefile[] = {
4140 	"",
4141 	0
4142 };
4143 
4144 void
send_file_list(char * whichf)4145 send_file_list(char *whichf)
4146 {
4147 	struct stat st;
4148 	DIR *dirp = NULL;
4149 	struct dirent *dir;
4150 	FILE *dout = NULL;
4151 	char **dirlist, *dirname;
4152 	int simple = 0;
4153 	int freeglob = 0;
4154 	glob_t gl;
4155 	char buf[BUFSIZ + MAXPATHLEN];
4156 
4157 	if (strpbrk(whichf, "~{[*?") != NULL) {
4158 		int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_TILDE;
4159 
4160 		memset(&gl, 0, sizeof(gl));
4161 		gl.gl_matchc = MAXGLOBARGS;
4162 		flags |= GLOB_LIMIT;
4163 		freeglob = 1;
4164 #ifdef LINUX /* Linux port */
4165 		if (bsdglob(whichf, flags, 0, &gl)) {
4166 #else /* BSD source */
4167 		if (glob(whichf, flags, 0, &gl)) {
4168 #endif /* BSD source */
4169 			reply(550, "No matching files found.");
4170 			goto out;
4171 		} else if (gl.gl_pathc == 0) {
4172 			errno = ENOENT;
4173 			perror_reply(550, whichf);
4174 			goto out;
4175 		}
4176 		dirlist = gl.gl_pathv;
4177 	} else {
4178 		onefile[0] = whichf;
4179 		dirlist = onefile;
4180 		simple = 1;
4181 	}
4182 
4183 	while ((dirname = *dirlist++)) {
4184 		if (stat(dirname, &st) < 0) {
4185 			/*
4186 			 * If user typed "ls -l", etc, and the client
4187 			 * used NLST, do what the user meant.
4188 			 */
4189 			if (dirname[0] == '-' && *dirlist == NULL &&
4190 			    transflag == 0) {
4191 				retrieve(_PATH_LS " %s", dirname);
4192 				goto out;
4193 			}
4194 			perror_reply(550, whichf);
4195 			if (dout != NULL) {
4196 #ifdef USE_SSL
4197 				if (ssl_data_active_flag &&
4198 				    (ssl_data_con != NULL)) {
4199 					if (SSL_shutdown(ssl_data_con) == 0) {
4200 					    switch (SSL_get_shutdown(ssl_data_con)) {
4201 					    case SSL_SENT_SHUTDOWN:
4202 						SSL_get_shutdown(ssl_data_con);
4203 						break;
4204 					    default:
4205 						break;
4206 					    }
4207 					}
4208 					SSL_free(ssl_data_con);
4209 					ssl_data_active_flag = 0;
4210 					ssl_data_con = NULL;
4211 				}
4212 #endif /* USE_SSL */
4213 				(void) fclose(dout);
4214 				transflag = 0;
4215 				data = -1;
4216 				pdata = -1;
4217 			}
4218 			goto out;
4219 		}
4220 
4221 		if (S_ISREG(st.st_mode)) {
4222 			if (dout == NULL) {
4223 				dout = dataconn("file list", -1, "w");
4224 				if (dout == NULL)
4225 					goto out;
4226 				transflag++;
4227 			}
4228 			snprintf(buf, sizeof(buf), "%s%s\n", dirname,
4229 				type == TYPE_A ? "\r" : "");
4230 #ifdef USE_SSL
4231 			if (ssl_data_active_flag)
4232 				ssl_write(ssl_data_con, buf, strlen(buf));
4233 			else
4234 #endif /* USE_SSL */
4235 				fwrite(buf, strlen(buf), 1, dout);
4236 			byte_count += strlen(dirname) + 1;
4237 			continue;
4238 		} else if (!S_ISDIR(st.st_mode))
4239 			continue;
4240 
4241 		if ((dirp = opendir(dirname)) == NULL)
4242 			continue;
4243 
4244 		while ((dir = readdir(dirp)) != NULL) {
4245 			char nbuf[MAXPATHLEN];
4246 
4247 			if (recvurg)
4248 				if (myoob()) {
4249 					recvurg = 0;
4250 					transflag = 0;
4251 					goto out;
4252 				}
4253 
4254 #ifdef LINUX
4255 			if (dir->d_name[0] == '.' && dir->d_name[1] == '\0')
4256 				continue;
4257 			if (dir->d_name[0] == '.' && dir->d_name[1] == '.' &&
4258 			    dir->d_name[2] == '\0')
4259 				continue;
4260 #else /* BSD source */
4261 			if (dir->d_name[0] == '.' && dir->d_namlen == 1)
4262 				continue;
4263 			if (dir->d_name[0] == '.' && dir->d_name[1] == '.' &&
4264 			    dir->d_namlen == 2)
4265 				continue;
4266 #endif /* BSD source */
4267 
4268 			snprintf(nbuf, sizeof(nbuf),
4269 				"%s/%s", dirname, dir->d_name);
4270 
4271 			/*
4272 			 * We have to do a stat to insure it's
4273 			 * not a directory or special file.
4274 			 */
4275 			if (simple || (stat(nbuf, &st) == 0 &&
4276 			    S_ISREG(st.st_mode))) {
4277 				if (dout == NULL) {
4278 					dout = dataconn("file list", -1, "w");
4279 					if (dout == NULL)
4280 						goto out;
4281 					transflag++;
4282 				}
4283 				if (nbuf[0] == '.' && nbuf[1] == '/')
4284 					snprintf(buf, sizeof(buf),
4285 					         "%s%s\n", &nbuf[2],
4286 					         type == TYPE_A ? "\r" : "");
4287 				else
4288 					snprintf(buf, sizeof(buf),
4289 					         "%s%s\n", nbuf,
4290 						 type == TYPE_A ? "\r" : "");
4291 #ifdef USE_SSL
4292 				if (ssl_data_active_flag)
4293 					ssl_write(ssl_data_con, buf, strlen(buf));
4294 				else
4295 #endif /* USE_SSL */
4296 					fwrite(buf, strlen(buf), 1, dout);
4297 				byte_count += strlen(nbuf) + 1;
4298 			}
4299 		}
4300 		(void) closedir(dirp);
4301 	}
4302 
4303 	if (dout == NULL)
4304 		reply(550, "No files found.");
4305 	else if (ferror(dout) != 0)
4306 		perror_reply(550, "Data connection");
4307 	else
4308 		reply(226, "Transfer complete.");
4309 
4310 	transflag = 0;
4311 	if (dout != NULL) {
4312 #ifdef USE_SSL
4313 		if (ssl_data_active_flag && (ssl_data_con != NULL)) {
4314 			if (SSL_shutdown(ssl_data_con) == 0) {
4315 			    switch (SSL_get_shutdown(ssl_data_con)) {
4316 			    case SSL_SENT_SHUTDOWN:
4317 				SSL_get_shutdown(ssl_data_con);
4318 				break;
4319 			    default:
4320 				break;
4321 			    }
4322 			}
4323 			SSL_free(ssl_data_con);
4324 			ssl_data_active_flag = 0;
4325 			ssl_data_con = NULL;
4326 		}
4327 #endif /* USE_SSL */
4328 		(void) fclose(dout);
4329 	}
4330 	data = -1;
4331 	pdata = -1;
4332 out:
4333 	if (freeglob) {
4334 		freeglob = 0;
4335 		globfree(&gl);
4336 	}
4337 }
4338 
4339 void
4340 reapchild(int signo)
4341 {
4342 	while (waitpid(-1, NULL, WNOHANG) > 0);
4343 }
4344 
4345 #ifdef OLD_SETPROCTITLE
4346 /*
4347  * Clobber argv so ps will show what we're doing.  (Stolen from sendmail.)
4348  * Warning, since this is usually started from inetd.conf, it often doesn't
4349  * have much of an environment or arglist to overwrite.
4350  */
4351 void
4352 setproctitle(const char *fmt, ...)
4353 {
4354 	int i;
4355 	va_list ap;
4356 	char *p, *bp, ch;
4357 	char buf[LINE_MAX];
4358 
4359 	va_start(ap, fmt);
4360 	(void)vsnprintf(buf, sizeof(buf), fmt, ap);
4361 
4362 	/* make ps print our process name */
4363 	p = Argv[0];
4364 	*p++ = '-';
4365 
4366 	i = strlen(buf);
4367 	if (i > LastArgv - p - 2) {
4368 		i = LastArgv - p - 2;
4369 		buf[i] = '\0';
4370 	}
4371 	bp = buf;
4372 	while (ch = *bp++)
4373 		if (ch != '\n' && ch != '\r')
4374 			*p++ = ch;
4375 	while (p < LastArgv)
4376 		*p++ = ' ';
4377 }
4378 #endif /* OLD_SETPROCTITLE */
4379 
4380 static void
4381 appendf(char **strp, char *fmt, ...)
4382 {
4383 	va_list ap;
4384 	char *ostr, *p;
4385 
4386 	va_start(ap, fmt);
4387 	vasprintf(&p, fmt, ap);
4388 	va_end(ap);
4389 	if (p == NULL)
4390 		fatalerror("Ran out of memory.");
4391 	if (*strp == NULL)
4392 		*strp = p;
4393 	else {
4394 		ostr = *strp;
4395 		asprintf(strp, "%s%s", ostr, p);
4396 		if (*strp == NULL)
4397 			fatalerror("Ran out of memory.");
4398 		free(ostr);
4399 	}
4400 }
4401 
4402 static void
4403 logcmd(char *cmd, char *file1, char *file2, off_t cnt)
4404 {
4405 	char *msg = NULL;
4406 	char wd[MAXPATHLEN + 1];
4407 
4408 	if (logging <= 1)
4409 		return;
4410 
4411 	if (getcwd(wd, sizeof(wd) - 1) == NULL)
4412 		snprintf(wd, sizeof(wd), "%s", strerror(errno));
4413 
4414 	appendf(&msg, "%s", cmd);
4415 	if (file1)
4416 		appendf(&msg, " %s", file1);
4417 	if (file2)
4418 		appendf(&msg, " %s", file2);
4419 	if (cnt >= 0)
4420 		appendf(&msg, " = %jd bytes", (intmax_t)cnt);
4421 	appendf(&msg, " (wd: %s", wd);
4422 	if (guest || dochroot)
4423 		appendf(&msg, "; chrooted");
4424 	appendf(&msg, ")");
4425 	syslog(LOG_INFO, "%s", msg);
4426 	free(msg);
4427 }
4428 
4429 /*
4430  * Log the transfer information.
4431  * arguments:
4432  *	cmd  - the name of the ftp(1) operation.
4433  *	name - the name of the file.
4434  *	size - the size of the file (not the size of the transfer!).
4435  *	time_start, time_end - the values of times (according to time(3)) of
4436  *		the begin and the end of transfer, respectively.
4437  *	outgoing_flag - is not 0 in case of outgoing transfer.
4438  *	err_flag - is not 0 if errors occurred during the transfer.
4439  * return:
4440  *	none.
4441  */
4442 static void
4443 logxfer(char *cmd, char *name, off_t size, time_t time_start, time_t time_end,
4444 	int outgoing_flag, int err_flag)
4445 {
4446 	/* don't use the own format for syslog if the wu-ftpd style format is
4447 	 * enabled */
4448 	if (!xferlog_syslog)
4449 		LOGBYTES(cmd, name, byte_count);
4450 
4451 	/* don't log to file in the own format if the wu-ftpd style one is
4452 	 * enabled */
4453 	if (!xferlog_stat && guest && stats && outgoing_flag && byte_count > 0)
4454 		logxfer_anon(name, byte_count, time_start, time_end);
4455 
4456 	/* use the wu-ftpd style xferlog if it is enabled */
4457 	if (xferlog_stat || xferlog_syslog)
4458 		logxfer_wuftpd(cmd, name, size, time_start, time_end,
4459 		    outgoing_flag, err_flag);
4460 }
4461 
4462 /*
4463  * Log anonymous file downloads.
4464  * arguments:
4465  *	name - the name of the file.
4466  *	size - the size of the file (can be the size of the transfer).
4467  *	time_start, time_end - the values of times (according to time(3)) of
4468  *		the begin and the end of transfer, respectively.
4469  * return:
4470  *	none.
4471  */
4472 static void
4473 logxfer_anon(char *name, off_t size, time_t time_start, time_t time_end)
4474 {
4475 	char *buf = NULL;
4476 	char path[MAXPATHLEN + 1];
4477 
4478 	if (statfd >= 0) {
4479 		if (realpath(name, path) == NULL) {
4480 			syslog(LOG_WARNING, "realpath failed on '%s': %m", path);
4481 			return;
4482 		}
4483 		appendf(&buf, "%.20s!%s!%s!%s%s!%jd!%ld\n", ctime(&time_end) + 4,
4484 			ident, remotehost,
4485 			(guest || dochroot) && xferlog_anon_realroot &&
4486 			/* check the special case: a chroot directory and the
4487 			 * real root directory are the same */
4488 			rchrootdir[1] != 0 ?
4489 			rchrootdir : "", path, (intmax_t)size,
4490 			(long)(time_end-time_start + (time_end==time_start)));
4491 		write(statfd, buf, strlen(buf));
4492 		free(buf);
4493 	}
4494 }
4495 
4496 /*
4497  * Log the transfer information in the wu-ftpd style format.
4498  * arguments:
4499  *	cmd  - the name of the ftp(1) operation.
4500  *	name - the name of the file.
4501  *	size - the size of the file (not the size of the transfer!).
4502  *	time_start, time_end - the values of times (according to time(3)) of
4503  *		the begin and the end of transfer, respectively.
4504  *	outgoing_flag - is not 0 in case of outgoing transfer.
4505  *	err_flag - is not 0 if errors occurred during the transfer.
4506  * return:
4507  *	none.
4508  * notes:
4509  *	In case of an incoming transfer (outgoing_flag == 0) the "size" must
4510  *	be the size of the file AFTER the completion of the transfer.
4511  */
4512 static void
4513 logxfer_wuftpd(char *cmd, char *name, off_t size, time_t time_start,
4514 	    time_t time_end, int outgoing_flag, int err_flag)
4515 {
4516 	char *msg = NULL; /* original fields of the wu-ftpd xferlog */
4517 	char *msg_ext = NULL; /* extended fields of the xferlog */
4518 	char wd[MAXPATHLEN + 1], path[MAXPATHLEN + 1];
4519 	time_t xfertime = time_end - time_start + (time_end == time_start);
4520 	time_t curtime = time(NULL);
4521 
4522 	if (getcwd(wd, sizeof(wd)) == NULL) {
4523 		int errno_ori = errno;
4524 		syslog(LOG_WARNING, "getcwd failed: %m");
4525 		snprintf(wd, sizeof(wd), "'%s'", strerror(errno_ori));
4526 	}
4527 	if (realpath(name, path) == NULL) {
4528 		int errno_ori = errno;
4529 		syslog(LOG_WARNING, "realpath failed on '%s': %m", path);
4530 		snprintf(path, sizeof(path), "'%s'", strerror(errno_ori));
4531 	}
4532 
4533 	appendf(&msg, "%.24s %ld %s %jd %s%s %c %s %c %c %s ftp %d %s %c",
4534 		/* current-time in the form "DDD MMM dd hh:mm:ss YYYY" */
4535 		ctime(&curtime),
4536 		/* transfer-time (seconds) */
4537 		(long)xfertime,
4538 		/* remote-host */
4539 		remotehost,
4540 		/* byte-count (bytes) */
4541 		byte_count > 0 ? (intmax_t)byte_count : 0,
4542 		/* filename */
4543 		(guest || dochroot) && xferlog_wu_realroot &&
4544 		    /* check the special case: a chroot directory and the real
4545 		     * root directory are the same */
4546 		    rchrootdir[1] != 0 ?
4547 		    rchrootdir : "", path,
4548 		/* transfer-type (ascii/binary: [a|b]) */
4549 		type == TYPE_A ? 'a' : 'b',
4550 		/* special-action-flag (gzip/gunzip/tar/none: [C|U|T|_]) */
4551 		"_",
4552 		/* direction (incoming/outgoing: [i|o]) */
4553 		outgoing_flag ? 'o' : 'i',
4554 		/* access-mode (anonymous/guest/real user: [a|g|r]) */
4555 		guest ? 'a' : dochroot ? 'g' : 'r',
4556 		/* username (ident string/login name) */
4557 		guest ? ident : curname,
4558 		/* authentication-method (none/RFC931: [0|1]) */
4559 		0,
4560 		/* authentication-user-id; '*' if it isn't available */
4561 		"*",
4562 		/* completion-status (complete/incomplete: [c|i]) */
4563 		err_flag ? 'i' : 'c'
4564 	);
4565 
4566 	if (xferlog_stat == XFERLOG_EXT || xferlog_syslog == XFERLOG_EXT) {
4567 		appendf(&msg_ext, " %jd %jd %s %s %s",
4568 		/* restart-point (bytes), file-size (bytes) */
4569 		(intmax_t)restart_point, (intmax_t)size,
4570 		/* cwd, filename-arg */
4571 		wd, name,
4572 		/* protection-level
4573 		 * (Clear/Safe/Confidential/Private: [C|S|E|P]) */
4574 #ifdef USE_SSL
4575 		ssl_encrypt_data ? "P" : "C");
4576 #else /* !USE_SSL */
4577 		"C");
4578 #endif /* USE_SSL */
4579 	}
4580 
4581 	if (xferlog_syslog)
4582 		syslog(LOG_INFO, "xferlog (%s): %s%s",
4583 		    /* The extended format or... */
4584 		    xferlog_syslog == XFERLOG_EXT ? cmd :
4585 		    /* ...the original wu-ftpd one */
4586 		    (outgoing_flag ? "send" : "recv"),
4587 		    /* Skip date/time */
4588 		    msg + 25,
4589 		    /* Append extended fields */
4590 		    xferlog_syslog == XFERLOG_EXT ? msg_ext : "");
4591 
4592 	if (statfd >= 0 && xferlog_stat) {
4593 		/* Append '\n' and extended fields */
4594 		appendf(&msg, "%s\n",
4595 		    xferlog_stat == XFERLOG_EXT ? msg_ext: "");
4596 
4597 		write(statfd, msg, strlen(msg));
4598 	}
4599 
4600 	free(msg);
4601 	free(msg_ext);
4602 }
4603 
4604 static char *
4605 doublequote(char *s)
4606 {
4607 	int n;
4608 	char *p, *s2;
4609 
4610 	for (p = s, n = 0; *p; p++)
4611 		if (*p == '"')
4612 			n++;
4613 
4614 	if ((s2 = malloc(p - s + n + 1)) == NULL)
4615 		return (NULL);
4616 
4617 	for (p = s2; *s; s++, p++) {
4618 		if ((*p = *s) == '"')
4619 			*(++p) = '"';
4620 	}
4621 	*p = '\0';
4622 
4623 	return (s2);
4624 }
4625 
4626 /* setup server socket for specified address family */
4627 /* if af is PF_UNSPEC more than one socket may be returned */
4628 /* the returned list is dynamically allocated, so caller needs to free it */
4629 static int *
4630 socksetup(int af, char *bindname, const char *bindport)
4631 {
4632 	struct addrinfo hints, *res, *r;
4633 	int error, maxs, *s, *socks;
4634 	const int on = 1;
4635 
4636 	memset(&hints, 0, sizeof(hints));
4637 	hints.ai_flags = AI_PASSIVE;
4638 	hints.ai_family = af;
4639 	hints.ai_socktype = SOCK_STREAM;
4640 	error = getaddrinfo(bindname, bindport, &hints, &res);
4641 	if (error) {
4642 		syslog(LOG_ERR, "%s", gai_strerror(error));
4643 		if (error == EAI_SYSTEM)
4644 			syslog(LOG_ERR, "%s", strerror(errno));
4645 		return NULL;
4646 	}
4647 
4648 	/* Count max number of sockets we may open */
4649 	for (maxs = 0, r = res; r; r = r->ai_next, maxs++)
4650 		;
4651 	socks = malloc((maxs + 1) * sizeof(int));
4652 	if (!socks) {
4653 		freeaddrinfo(res);
4654 		syslog(LOG_ERR, "couldn't allocate memory for sockets");
4655 		return NULL;
4656 	}
4657 
4658 	*socks = 0;   /* num of sockets counter at start of array */
4659 	s = socks + 1;
4660 	for (r = res; r; r = r->ai_next) {
4661 		*s = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
4662 		if (*s < 0) {
4663 			syslog(LOG_DEBUG, "control socket: %m");
4664 			continue;
4665 		}
4666 		if (setsockopt(*s, SOL_SOCKET, SO_REUSEADDR,
4667 		    &on, sizeof(on)) < 0)
4668 			syslog(LOG_WARNING,
4669 			    "control setsockopt (SO_REUSEADDR): %m");
4670 #if defined(INET6) && defined(IPV6_V6ONLY)
4671 		/* In Linux, IPV6_V6ONLY socket option does not exist in
4672 		 * kernel 2.4.20 or earlier... */
4673 		if (r->ai_family == AF_INET6) {
4674 			if (setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY,
4675 			    &on, sizeof(on)) < 0)
4676 				syslog(LOG_WARNING,
4677 				    "control setsockopt (IPV6_V6ONLY): %m");
4678 		}
4679 #endif /* INET6 */
4680 		if (bind(*s, r->ai_addr, r->ai_addrlen) < 0) {
4681 			syslog(LOG_DEBUG, "control bind: %m");
4682 			close(*s);
4683 			continue;
4684 		}
4685 		(*socks)++;
4686 		s++;
4687 	}
4688 
4689 	if (res)
4690 		freeaddrinfo(res);
4691 
4692 	if (*socks == 0) {
4693 		syslog(LOG_ERR, "control socket: Couldn't bind to any socket");
4694 		free(socks);
4695 		return NULL;
4696 	}
4697 	return(socks);
4698 }
4699 
4700 #ifdef USE_SSL
4701 
4702 /*
4703  * Initialize the TLS/SSL session on a control connection.
4704  */
4705 void
4706 do_ssl_start()
4707 {
4708     char errstr[BUFSIZ];
4709     char *ssl_version;
4710     int ssl_bits;
4711     SSL_CIPHER *ssl_cipher;
4712 
4713     if (ssl_debug_flag)
4714 	    ssl_log_msgn(bio_err, "do_ssl_start triggered");
4715 
4716     /* Do the SSL stuff now... Before we play with pty's. */
4717     ssl_con = (SSL *)SSL_new(ssl_ctx);
4718     SSL_set_accept_state(ssl_con);
4719 
4720     /* We are working with stdin (inetd based) by default. */
4721     SSL_set_fd(ssl_con, 0);
4722 
4723     if (SSL_accept(ssl_con) <= 0) {
4724 	    switch (SSL_get_verify_result(ssl_con)) {
4725 	    case X509_V_ERR_CRL_SIGNATURE_FAILURE:
4726 		    snprintf(errstr, sizeof(errstr),
4727 			    "invalid signature on CRL!");
4728 		    break;
4729 	    case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
4730 		    snprintf(errstr, sizeof(errstr),
4731 			    "found CRL has invalid nextUpdate field");
4732 		    break;
4733 	    case X509_V_ERR_CRL_HAS_EXPIRED:
4734 		    snprintf(errstr, sizeof(errstr),
4735 			    "found CRL expired - revoking all certificates until you get updated CRL");
4736 		    break;
4737 	    case X509_V_ERR_CERT_REVOKED:
4738 		    snprintf(errstr, sizeof(errstr),
4739 			    "client certificate is revoked");
4740 		    break;
4741 	    default:
4742 		    snprintf(errstr, sizeof(errstr), "%s",
4743 			    ERR_reason_error_string(ERR_peek_error()));
4744 	    }
4745 
4746 	    if (logging)
4747 		    syslog(LOG_NOTICE, "TLS/SSL FAILED WITH %s (reason: %s)",
4748 			  remotehost, errstr);
4749 
4750 	    snprintf(errstr, sizeof(errstr), "SSL_accept: %s.",
4751 		    ERR_reason_error_string(ERR_get_error()));
4752 	    reply(421, "%s", errstr);
4753 
4754 	    SSL_free(ssl_con);
4755 	    ssl_con = NULL;
4756 
4757 	    dologout(1);
4758     } else {
4759 	    ssl_active_flag = 1;
4760 
4761 	    ssl_version = SSL_get_cipher_version(ssl_con);
4762 	    ssl_cipher = SSL_get_current_cipher(ssl_con);
4763 	    SSL_CIPHER_get_bits(ssl_cipher, &ssl_bits);
4764 
4765 	    if (logging)
4766         	    syslog(LOG_INFO,
4767 			"TLS/SSL SUCCEEDED WITH %s (%s, %s, cipher %s, %d bits)",
4768 			remotehost, ssl_compat_flag ? "FTP-SSL" : "FTP-TLS",
4769 			ssl_version, SSL_CIPHER_get_name(ssl_cipher), ssl_bits);
4770     }
4771 
4772     /*
4773      * ssl_fprintf calls require that this be null to test
4774      * for being an ssl stream.
4775      */
4776     if (!ssl_active_flag) {
4777 	    if (ssl_con != NULL)
4778 		    SSL_free(ssl_con);
4779 	    ssl_con = NULL;
4780     }
4781 }
4782 
4783 /*
4784  * Do the X.509 user authentication and log results
4785  * arguments:
4786  *	name - login name provided by the client.
4787  * return:
4788  *	1 - peer's X.509 certificate is authorized to use name.
4789  *	0 - otherwise, or if the peer doesn't provide the cert (for any reason,
4790  *	    include the unencrypted connection), or if errors occurred.
4791  */
4792 int
4793 good_ssl_user(name)
4794 char *name;
4795 {
4796     X509 *cert;
4797     int ret;
4798 
4799     if (!x509_auth_flag)
4800 	    return 0; /* can't happen */
4801 
4802     cert = SSL_get_peer_certificate(ssl_con);
4803     if (cert != NULL) {
4804 	    /* Do X.509 auth. */
4805 	    if (ssl_x509_auth(_SERVICE_NAME, cert, name) == 1) {
4806     		    ret = 1;
4807 	    } else {
4808 		    ret = 0;
4809 	    }
4810 	    if (logging)
4811     		    syslog(LOG_INFO, ret ?
4812 			"X.509 AUTH ACCEPTED FOR SUBJECT: %s" :
4813 			"X.509 AUTH REJECTED FOR SUBJECT: %s",
4814 			(char *)ONELINE_NAME(X509_get_subject_name(cert)));
4815     } else {
4816 	    /* Can't authenticate because no peer certificate provided. */
4817 	    ret = 0;
4818     }
4819 
4820     X509_free(cert);
4821     return ret;
4822 }
4823 
4824 #endif /* USE_SSL */
4825 
4826 #ifdef USE_PAM
4827 static void
4828 ftpd_openlog()
4829 {
4830     closelog();
4831 
4832     /*
4833      * LOG_NDELAY sets up the logging connection immediately,
4834      * necessary for anonymous ftp's that chroot and can't do it later.
4835      */
4836     openlog(_SERVICE_NAME, LOG_PID | LOG_NDELAY, LOG_FTP);
4837 }
4838 #endif /* USE_PAM */
4839 
4840 #ifdef TCPWRAPPERS
4841 static int
4842 check_host(struct sockaddr *sa)
4843 {
4844     struct request_info req;
4845 
4846     int error_name, error_addr;
4847     char sa_name[NI_MAXHOST], sa_addr[NI_MAXHOST];
4848 
4849     error_name = getnameinfo(sa,
4850 #ifdef LINUX /* Linux port */
4851 		SA_LEN(sa),
4852 #else /* BSD source */
4853 		sa->sa_len,
4854 #endif /* BSD source */
4855 		sa_name, sizeof(sa_name) - 1, NULL, 0, NI_NAMEREQD);
4856     error_addr = getnameinfo(sa,
4857 #ifdef LINUX /* Linux port */
4858 		SA_LEN(sa),
4859 #else /* BSD source */
4860 		sa->sa_len,
4861 #endif /* BSD source */
4862 		sa_addr, sizeof(sa_addr) - 1, NULL, 0, NI_NUMERICHOST);
4863 
4864     /* Fill req struct with port name and fd number. */
4865     if (!error_name) {
4866 	    request_init(&req, RQ_DAEMON, _SERVICE_NAME, RQ_CLIENT_NAME,
4867 		    sa_name, RQ_CLIENT_ADDR, error_addr == 0 ? sa_addr : "",
4868 		    RQ_USER, STRING_UNKNOWN, NULL);
4869     } else {
4870 	    request_init(&req, RQ_DAEMON, _SERVICE_NAME, RQ_CLIENT_NAME,
4871 		    STRING_UNKNOWN, RQ_CLIENT_ADDR, error_addr == 0 ? sa_addr :
4872 		    "", RQ_USER, STRING_UNKNOWN, NULL);
4873     }
4874 
4875     if (!hosts_access(&req)) {
4876 	    syslog(deny_severity, "connection from %.256s rejected by tcp_wrappers",
4877 		  eval_client(&req));
4878 	    return (0);
4879     }
4880 
4881     syslog(allow_severity, "connection from %.256s granted by tcp_wrappers",
4882 	  eval_client(&req));
4883     return (1);
4884 }
4885 #endif /* TCPWRAPPERS */
4886 
4887 /*
4888  * Set the global variable "tun_pasvip_addr", which is used to override the IP
4889  * address that will be advertised to IPv4 clients in response to the PASV/LPSV
4890  * commands.
4891  * arguments:
4892  *	tun_pasvip_str - the string that contains an IPv4 address or a symbolic
4893  *	                 host name, which is expected to be resolvable as
4894  *			 an IPv4 family address.
4895  * return:
4896  *	1 - an IPv4 family address has been successfully obtained from
4897  *	    "tun_pasvip_str".
4898  *	0 - otherwise, or if overriding of the IP address is turned off.
4899  * notes:
4900  *	The "tun_pasvip_str" string can contain an IP address or a symbolic
4901  *	host name, which will be resolved in DNS, but in daemon mode only
4902  *	the IP addresses are allowed.
4903  */
4904 static int
4905 set_pasvip_addr(char *tun_pasvip_str)
4906 {
4907     struct addrinfo hints, *res;
4908     int error;
4909 
4910     if (tun_pasvip_str == NULL || tun_pasvip_flag == 0) {
4911 	    tun_pasvip_flag = 0;
4912 	    return 0; /* unknown error */
4913     }
4914 
4915     memset(&hints, 0, sizeof(hints));
4916     hints.ai_family = AF_INET;
4917     hints.ai_addr = NULL;
4918     if (daemon_mode) {
4919 	    hints.ai_flags = AI_NUMERICHOST;
4920     }
4921 
4922     error = getaddrinfo(tun_pasvip_str, NULL, &hints, &res);
4923     if (error) {
4924 	    tun_pasvip_flag = 0;
4925 	    syslog(LOG_ERR, "can't set an IP address for passive mode: %s",
4926 		  gai_strerror(error));
4927 	    if (error == EAI_SYSTEM)
4928 		    syslog(LOG_ERR, "%s", strerror(errno));
4929 	    return 0;
4930     }
4931     if (res->ai_family != AF_INET || res->ai_addrlen > sizeof(tun_pasvip_addr)) {
4932 	    /* Can't obtain an IPv4 address. */
4933 	    tun_pasvip_flag = 0;
4934 	    syslog(LOG_ERR,
4935 		  "only an IPv4 family address may be used for PASV command");
4936 	    return 0;
4937     }
4938     memcpy(&tun_pasvip_addr, res->ai_addr, res->ai_addrlen);
4939 
4940     return 1; /* OK */
4941 }
4942 
4943 /*
4944  * An implementation of the FEAT command defined in RFC 2389. Note: the feature
4945  * names returned are not command names, as such, but simply indications that
4946  * the server possesses some attribute or other.
4947  */
4948 void
4949 feat(void)
4950 {
4951     struct feat_tab {
4952 	    char *name;
4953     };
4954 
4955     struct feat_tab feat_list[] = {
4956 #ifdef USE_SSL
4957 	    /* RFC 2228 */
4958 	    { "AUTH TLS" }, { "PBSZ" }, { "PROT" },
4959 #endif /* USE_SSL */
4960 	    /* RFC 3659 */
4961 	    { "SIZE" }, { "MDTM" }, { "REST STREAM" },
4962 	    { NULL }
4963     };
4964 
4965     struct feat_tab *c;
4966 
4967     lreply(211, "Extensions supported:");
4968     for (c = feat_list; c->name != NULL; c++)
4969 	    PRINTF(" %s\r\n", c->name);
4970     FFLUSH(stdout);
4971     reply(211, "End.");
4972 }
4973