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