ftpd.c revision 1.221
1/* $OpenBSD: ftpd.c,v 1.221 2016/08/31 13:43:36 jca Exp $ */ 2/* $NetBSD: ftpd.c,v 1.15 1995/06/03 22:46:47 mycroft Exp $ */ 3 4/* 5 * Copyright (C) 1997 and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33/* 34 * Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994 35 * The Regents of the University of California. All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. Neither the name of the University nor the names of its contributors 46 * may be used to endorse or promote products derived from this software 47 * without specific prior written permission. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 * SUCH DAMAGE. 60 */ 61 62/* 63 * FTP server. 64 */ 65#include <sys/stat.h> 66#include <sys/ioctl.h> 67#include <sys/socket.h> 68#include <sys/wait.h> 69#include <sys/mman.h> 70 71#include <netinet/in.h> 72#include <netinet/ip.h> 73#include <netinet/tcp.h> 74 75#define FTP_NAMES 76#include <arpa/ftp.h> 77#include <arpa/inet.h> 78#include <arpa/telnet.h> 79 80#include <bsd_auth.h> 81#include <ctype.h> 82#include <dirent.h> 83#include <errno.h> 84#include <fcntl.h> 85#include <glob.h> 86#include <limits.h> 87#include <login_cap.h> 88#include <netdb.h> 89#include <pwd.h> 90#include <signal.h> 91#include <stdarg.h> 92#include <stdio.h> 93#include <stdlib.h> 94#include <string.h> 95#include <syslog.h> 96#include <time.h> 97#include <vis.h> 98#include <unistd.h> 99#include <utmp.h> 100#include <poll.h> 101 102#include "pathnames.h" 103#include "monitor.h" 104#include "extern.h" 105 106extern off_t restart_point; 107extern char cbuf[]; 108 109union sockunion ctrl_addr; 110union sockunion data_source; 111union sockunion data_dest; 112union sockunion his_addr; 113union sockunion pasv_addr; 114 115sigset_t allsigs; 116 117int daemon_mode = 0; 118int data; 119int logged_in; 120struct passwd *pw; 121int debug = 0; 122int timeout = 900; /* timeout after 15 minutes of inactivity */ 123int maxtimeout = 7200;/* don't allow idle time to be set beyond 2 hours */ 124int logging; 125int anon_ok = 1; 126int anon_only = 0; 127unsigned int minuid = 1000; 128int multihome = 0; 129int guest; 130int stats; 131int statfd = -1; 132int portcheck = 1; 133int dochroot; 134int type; 135int form; 136int stru; /* avoid C keyword */ 137int mode; 138int doutmp = 0; /* update utmp file */ 139int nowtmp = 0; /* do not update wtmp file */ 140int usedefault = 1; /* for data transfers */ 141int pdata = -1; /* for passive mode */ 142int family = AF_UNSPEC; 143volatile sig_atomic_t transflag; 144off_t file_size; 145off_t byte_count; 146mode_t defumask = S_IWGRP|S_IWOTH; /* default umask value */ 147int umaskchange = 1; /* allow user to change umask value. */ 148char tmpline[7]; 149char hostname[HOST_NAME_MAX+1]; 150char remotehost[HOST_NAME_MAX+1]; 151char dhostname[HOST_NAME_MAX+1]; 152char *guestpw; 153char ttyline[20]; 154static struct utmp utmp; /* for utmp */ 155static login_cap_t *lc; 156static auth_session_t *as; 157static volatile sig_atomic_t recvurg; 158 159int epsvall = 0; 160 161/* 162 * Timeout intervals for retrying connections 163 * to hosts that don't accept PORT cmds. This 164 * is a kludge, but given the problems with TCP... 165 */ 166#define SWAITMAX 90 /* wait at most 90 seconds */ 167#define SWAITINT 5 /* interval between retries */ 168 169int swaitmax = SWAITMAX; 170int swaitint = SWAITINT; 171 172char proctitle[BUFSIZ]; /* initial part of title */ 173 174#define LOGCMD(cmd, file) \ 175 if (logging > 1) \ 176 syslog(LOG_INFO,"%s %s%s", cmd, \ 177 *(file) == '/' ? "" : curdir(), file); 178#define LOGCMD2(cmd, file1, file2) \ 179 if (logging > 1) \ 180 syslog(LOG_INFO,"%s %s%s %s%s", cmd, \ 181 *(file1) == '/' ? "" : curdir(), file1, \ 182 *(file2) == '/' ? "" : curdir(), file2); 183#define LOGBYTES(cmd, file, cnt) \ 184 if (logging > 1) { \ 185 if ((cnt) == -1) \ 186 syslog(LOG_INFO,"%s %s%s", cmd, \ 187 *(file) == '/' ? "" : curdir(), file); \ 188 else \ 189 syslog(LOG_INFO, "%s %s%s = %lld bytes", \ 190 cmd, (*(file) == '/') ? "" : curdir(), file, \ 191 (long long)(cnt)); \ 192 } 193 194static void ack(char *); 195static void sigurg(int); 196static void myoob(void); 197static int checkuser(char *, char *); 198static FILE *dataconn(char *, off_t, char *); 199static void dolog(struct sockaddr *); 200static char *copy_dir(char *, struct passwd *); 201static char *curdir(void); 202static void end_login(void); 203static FILE *getdatasock(char *); 204static int guniquefd(char *, char **); 205static void lostconn(int); 206static void sigquit(int); 207static int receive_data(FILE *, FILE *); 208static void replydirname(const char *, const char *); 209static int send_data(FILE *, FILE *, off_t, off_t, int); 210static struct passwd * 211 sgetpwnam(char *, struct passwd *); 212static void reapchild(int); 213static void usage(void); 214 215void logxfer(char *, off_t, time_t); 216void set_slave_signals(void); 217 218static char * 219curdir(void) 220{ 221 static char path[PATH_MAX+1]; /* path + '/' */ 222 223 if (getcwd(path, sizeof(path)-1) == NULL) 224 return (""); 225 if (path[1] != '\0') /* special case for root dir. */ 226 strlcat(path, "/", sizeof path); 227 /* For guest account, skip / since it's chrooted */ 228 return (guest ? path+1 : path); 229} 230 231char *argstr = "AdDhnlm:MSt:T:u:PUvW46"; 232 233static void 234usage(void) 235{ 236 syslog(LOG_ERR, 237 "usage: ftpd [-46ADdlMnPSUW] [-m minuid] [-T maxtimeout] " 238 "[-t timeout] [-u mask]"); 239 exit(2); 240} 241 242int 243main(int argc, char *argv[]) 244{ 245 socklen_t addrlen; 246 int ch, on = 1, tos; 247 char line[LINE_MAX]; 248 FILE *fp; 249 struct hostent *hp; 250 struct sigaction sa; 251 int error = 0; 252 const char *errstr; 253 254 tzset(); /* in case no timezone database in ~ftp */ 255 sigfillset(&allsigs); /* used to block signals while root */ 256 sigemptyset(&sa.sa_mask); 257 sa.sa_flags = SA_RESTART; 258 259 while ((ch = getopt(argc, argv, argstr)) != -1) { 260 switch (ch) { 261 case 'A': 262 anon_only = 1; 263 break; 264 265 case 'd': 266 case 'v': /* deprecated */ 267 debug = 1; 268 break; 269 270 case 'D': 271 daemon_mode = 1; 272 break; 273 274 case 'P': 275 portcheck = 0; 276 break; 277 278 case 'h': /* deprecated */ 279 break; 280 281 case 'l': 282 logging++; /* > 1 == extra logging */ 283 break; 284 285 case 'm': 286 minuid = strtonum(optarg, 0, UINT_MAX, &errstr); 287 if (errstr) { 288 syslog(LOG_ERR, 289 "%s is a bad value for -m, aborting", 290 optarg); 291 exit(2); 292 } 293 break; 294 295 case 'M': 296 multihome = 1; 297 break; 298 299 case 'n': 300 anon_ok = 0; 301 break; 302 303 case 'S': 304 stats = 1; 305 break; 306 307 case 't': 308 timeout = strtonum(optarg, 0, INT_MAX, &errstr); 309 if (errstr) { 310 syslog(LOG_ERR, 311 "%s is a bad value for -t, aborting", 312 optarg); 313 exit(2); 314 } 315 if (maxtimeout < timeout) 316 maxtimeout = timeout; 317 break; 318 319 case 'T': 320 maxtimeout = strtonum(optarg, 0, INT_MAX, 321 &errstr); 322 if (errstr) { 323 syslog(LOG_ERR, 324 "%s is a bad value for -T, aborting", 325 optarg); 326 exit(2); 327 } 328 if (timeout > maxtimeout) 329 timeout = maxtimeout; 330 break; 331 332 case 'u': 333 { 334 long val = 0; 335 char *p; 336 umaskchange = 0; 337 338 val = strtol(optarg, &p, 8); 339 if (*optarg == '\0' || *p != '\0' || val < 0 || 340 (val & ~ACCESSPERMS)) { 341 syslog(LOG_ERR, 342 "%s is a bad value for -u, aborting", 343 optarg); 344 exit(2); 345 } 346 defumask = val; 347 break; 348 } 349 350 case 'U': 351 doutmp = 1; 352 break; 353 354 case 'W': 355 nowtmp = 1; 356 break; 357 358 case '4': 359 family = AF_INET; 360 break; 361 362 case '6': 363 family = AF_INET6; 364 break; 365 366 default: 367 usage(); 368 break; 369 } 370 } 371 372 if (nowtmp && doutmp) { 373 syslog(LOG_ERR, "options 'U' and 'W' are mutually exclusive"); 374 exit(1); 375 } 376 377 (void) freopen(_PATH_DEVNULL, "w", stderr); 378 379 /* 380 * LOG_NDELAY sets up the logging connection immediately, 381 * necessary for anonymous ftp's that chroot and can't do it later. 382 */ 383 openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP); 384 385 if (getpwnam(FTPD_PRIVSEP_USER) == NULL) { 386 syslog(LOG_ERR, "privilege separation user %s not found", 387 FTPD_PRIVSEP_USER); 388 exit(1); 389 } 390 endpwent(); 391 392 if (daemon_mode) { 393 int *fds, i, fd; 394 struct pollfd *pfds; 395 struct addrinfo hints, *res, *res0; 396 nfds_t n; 397 398 /* 399 * Detach from parent. 400 */ 401 if (daemon(1, 1) < 0) { 402 syslog(LOG_ERR, "failed to become a daemon"); 403 exit(1); 404 } 405 sa.sa_handler = reapchild; 406 (void) sigaction(SIGCHLD, &sa, NULL); 407 408 memset(&hints, 0, sizeof(hints)); 409 hints.ai_family = family; 410 hints.ai_socktype = SOCK_STREAM; 411 hints.ai_protocol = IPPROTO_TCP; 412 hints.ai_flags = AI_PASSIVE; 413 error = getaddrinfo(NULL, "ftp", &hints, &res0); 414 if (error) { 415 syslog(LOG_ERR, "%s", gai_strerror(error)); 416 exit(1); 417 } 418 419 n = 0; 420 for (res = res0; res; res = res->ai_next) 421 n++; 422 423 fds = calloc(n, sizeof(int)); 424 pfds = calloc(n, sizeof(struct pollfd)); 425 if (!fds || !pfds) { 426 syslog(LOG_ERR, "%s", strerror(errno)); 427 exit(1); 428 } 429 430 /* 431 * Open sockets, bind it to the FTP port, and start 432 * listening. 433 */ 434 n = 0; 435 for (res = res0; res; res = res->ai_next) { 436 fds[n] = socket(res->ai_family, res->ai_socktype, 437 res->ai_protocol); 438 if (fds[n] < 0) 439 continue; 440 441 if (setsockopt(fds[n], SOL_SOCKET, SO_KEEPALIVE, 442 &on, sizeof(on)) < 0) { 443 close(fds[n]); 444 fds[n] = -1; 445 continue; 446 } 447 448 if (setsockopt(fds[n], SOL_SOCKET, SO_REUSEADDR, 449 &on, sizeof(on)) < 0) { 450 close(fds[n]); 451 fds[n] = -1; 452 continue; 453 } 454 455 if (bind(fds[n], res->ai_addr, res->ai_addrlen) < 0) { 456 close(fds[n]); 457 fds[n] = -1; 458 continue; 459 } 460 if (listen(fds[n], 32) < 0) { 461 close(fds[n]); 462 fds[n] = -1; 463 continue; 464 } 465 466 pfds[n].fd = fds[n]; 467 pfds[n].events = POLLIN; 468 n++; 469 } 470 freeaddrinfo(res0); 471 472 if (n == 0) { 473 syslog(LOG_ERR, "could not open control socket"); 474 exit(1); 475 } 476 477 /* 478 * Loop forever accepting connection requests and forking off 479 * children to handle them. 480 */ 481 while (1) { 482 if (poll(pfds, n, INFTIM) < 0) { 483 if (errno == EINTR) 484 continue; 485 syslog(LOG_ERR, "poll: %m"); 486 exit(1); 487 } 488 for (i = 0; i < n; i++) 489 if (pfds[i].revents & POLLIN) { 490 addrlen = sizeof(his_addr); 491 fd = accept(pfds[i].fd, 492 (struct sockaddr *)&his_addr, 493 &addrlen); 494 if (fd != -1) { 495 if (fork() == 0) 496 goto child; 497 close(fd); 498 } 499 } 500 } 501 502 child: 503 /* child */ 504 (void)dup2(fd, STDIN_FILENO); 505 (void)dup2(fd, STDOUT_FILENO); 506 for (i = 0; i < n; i++) 507 close(fds[i]); 508 } else { 509 addrlen = sizeof(his_addr); 510 if (getpeername(0, (struct sockaddr *)&his_addr, 511 &addrlen) < 0) { 512 /* syslog(LOG_ERR, "getpeername (%s): %m", argv[0]); */ 513 exit(1); 514 } 515 } 516 517 /* set this here so klogin can use it... */ 518 (void)snprintf(ttyline, sizeof(ttyline), "ftp%ld", (long)getpid()); 519 520 set_slave_signals(); 521 522 addrlen = sizeof(ctrl_addr); 523 if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) { 524 syslog(LOG_ERR, "getsockname: %m"); 525 exit(1); 526 } 527 if (his_addr.su_family == AF_INET6 && 528 IN6_IS_ADDR_V4MAPPED(&his_addr.su_sin6.sin6_addr)) { 529 syslog(LOG_WARNING, 530 "Connection from IPv4 mapped address is not supported."); 531 reply(530, "System not available."); 532 exit(1); 533 } 534 if (his_addr.su_family == AF_INET) { 535 tos = IPTOS_LOWDELAY; 536 if (setsockopt(0, IPPROTO_IP, IP_TOS, &tos, 537 sizeof(int)) < 0) 538 syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); 539 } 540 data_source.su_port = htons(ntohs(ctrl_addr.su_port) - 1); 541 542 /* Try to handle urgent data inline */ 543 if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on)) < 0) 544 syslog(LOG_ERR, "setsockopt: %m"); 545 546 dolog((struct sockaddr *)&his_addr); 547 548 /* 549 * Set up default state 550 */ 551 data = -1; 552 type = TYPE_A; 553 form = FORM_N; 554 stru = STRU_F; 555 mode = MODE_S; 556 tmpline[0] = '\0'; 557 558 /* If logins are disabled, print out the message. */ 559 if ((fp = fopen(_PATH_NOLOGIN, "r")) != NULL) { 560 while (fgets(line, sizeof(line), fp) != NULL) { 561 line[strcspn(line, "\n")] = '\0'; 562 lreply(530, "%s", line); 563 } 564 (void) fflush(stdout); 565 (void) fclose(fp); 566 reply(530, "System not available."); 567 exit(0); 568 } 569 if ((fp = fopen(_PATH_FTPWELCOME, "r")) != NULL) { 570 while (fgets(line, sizeof(line), fp) != NULL) { 571 line[strcspn(line, "\n")] = '\0'; 572 lreply(220, "%s", line); 573 } 574 (void) fflush(stdout); 575 (void) fclose(fp); 576 /* reply(220,) must follow */ 577 } 578 (void) gethostname(hostname, sizeof(hostname)); 579 580 /* Make sure hostname is fully qualified. */ 581 hp = gethostbyname(hostname); 582 if (hp != NULL) 583 strlcpy(hostname, hp->h_name, sizeof(hostname)); 584 585 if (multihome) { 586 error = getnameinfo((struct sockaddr *)&ctrl_addr, 587 ctrl_addr.su_len, dhostname, sizeof(dhostname), NULL, 0, 0); 588 } 589 590 if (error != 0) 591 reply(220, "FTP server ready."); 592 else 593 reply(220, "%s FTP server ready.", 594 (multihome ? dhostname : hostname)); 595 596 monitor_init(); 597 598 for (;;) 599 (void) yyparse(); 600 /* NOTREACHED */ 601} 602 603/* 604 * Signal handlers. 605 */ 606/*ARGSUSED*/ 607static void 608lostconn(int signo) 609{ 610 struct syslog_data sdata = SYSLOG_DATA_INIT; 611 612 sdata.log_fac = LOG_FTP; 613 if (debug) 614 syslog_r(LOG_DEBUG, &sdata, "lost connection"); 615 dologout(1); 616} 617 618static void 619sigquit(int signo) 620{ 621 struct syslog_data sdata = SYSLOG_DATA_INIT; 622 623 sdata.log_fac = LOG_FTP; 624 syslog_r(LOG_DEBUG, &sdata, "got signal %s", sys_signame[signo]); 625 dologout(1); 626} 627 628/* 629 * Save the result of a getpwnam. Used for USER command, since 630 * the data returned must not be clobbered by any other command 631 * (e.g., globbing). 632 */ 633static struct passwd * 634sgetpwnam(char *name, struct passwd *pw) 635{ 636 static struct passwd *save; 637 struct passwd *old; 638 639 if (pw == NULL && (pw = getpwnam(name)) == NULL) 640 return (NULL); 641 old = save; 642 save = pw_dup(pw); 643 if (save == NULL) { 644 perror_reply(421, "Local resource failure: malloc"); 645 dologout(1); 646 /* NOTREACHED */ 647 } 648 if (old) { 649 explicit_bzero(old->pw_passwd, strlen(old->pw_passwd)); 650 free(old); 651 } 652 return (save); 653} 654 655static int login_attempts; /* number of failed login attempts */ 656static int askpasswd; /* had user command, ask for passwd */ 657static char curname[LOGIN_NAME_MAX]; /* current USER name */ 658 659/* 660 * USER command. 661 * Sets global passwd pointer pw if named account exists and is acceptable; 662 * sets askpasswd if a PASS command is expected. If logged in previously, 663 * need to reset state. If name is "ftp" or "anonymous", the name is not in 664 * _PATH_FTPUSERS, and ftp account exists, set guest and pw, then just return. 665 * If account doesn't exist, ask for passwd anyway. Otherwise, check user 666 * requesting login privileges. Disallow anyone who does not have a standard 667 * shell as returned by getusershell(). Disallow anyone mentioned in the file 668 * _PATH_FTPUSERS to allow people such as root and uucp to be avoided. 669 */ 670void 671user(char *name) 672{ 673 char *cp, *shell, *style, *host; 674 char *class = NULL; 675 676 if (logged_in) { 677 kill_slave("user already logged in"); 678 end_login(); 679 } 680 681 /* Close session from previous user if there was one. */ 682 if (as) { 683 auth_close(as); 684 as = NULL; 685 } 686 if (lc) { 687 login_close(lc); 688 lc = NULL; 689 } 690 691 if ((style = strchr(name, ':')) != NULL) 692 *style++ = 0; 693 694 guest = 0; 695 askpasswd = 0; 696 host = multihome ? dhostname : hostname; 697 if (anon_ok && 698 (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0)) { 699 if (checkuser(_PATH_FTPUSERS, "ftp") || 700 checkuser(_PATH_FTPUSERS, "anonymous")) 701 reply(530, "User %s access denied.", name); 702 else if ((pw = sgetpwnam("ftp", NULL)) != NULL) { 703 if ((lc = login_getclass(pw->pw_class)) == NULL || 704 (as = auth_open()) == NULL || 705 auth_setpwd(as, pw) != 0 || 706 auth_setoption(as, "FTPD_HOST", host) < 0) { 707 if (as) { 708 auth_close(as); 709 as = NULL; 710 } 711 if (lc) { 712 login_close(lc); 713 lc = NULL; 714 } 715 reply(421, "Local resource failure"); 716 return; 717 } 718 guest = 1; 719 askpasswd = 1; 720 reply(331, 721 "Guest login ok, send your email address as password."); 722 } else 723 reply(530, "User %s unknown.", name); 724 if (!askpasswd && logging) 725 syslog(LOG_NOTICE, 726 "ANONYMOUS FTP LOGIN REFUSED FROM %s", remotehost); 727 return; 728 } 729 730 shell = _PATH_BSHELL; 731 if ((pw = sgetpwnam(name, NULL))) { 732 class = pw->pw_class; 733 if (pw->pw_shell != NULL && *pw->pw_shell != '\0') 734 shell = pw->pw_shell; 735 while ((cp = getusershell()) != NULL) 736 if (strcmp(cp, shell) == 0) 737 break; 738 shell = cp; 739 endusershell(); 740 } 741 742 /* Get login class; if invalid style treat like unknown user. */ 743 lc = login_getclass(class); 744 if (lc && (style = login_getstyle(lc, style, "auth-ftp")) == NULL) { 745 login_close(lc); 746 lc = NULL; 747 pw = NULL; 748 } 749 750 /* Do pre-authentication setup. */ 751 if (lc && ((as = auth_open()) == NULL || 752 (pw != NULL && auth_setpwd(as, pw) != 0) || 753 auth_setitem(as, AUTHV_STYLE, style) < 0 || 754 auth_setitem(as, AUTHV_NAME, name) < 0 || 755 auth_setitem(as, AUTHV_CLASS, class) < 0 || 756 auth_setoption(as, "login", "yes") < 0 || 757 auth_setoption(as, "notickets", "yes") < 0 || 758 auth_setoption(as, "FTPD_HOST", host) < 0)) { 759 if (as) { 760 auth_close(as); 761 as = NULL; 762 } 763 login_close(lc); 764 lc = NULL; 765 reply(421, "Local resource failure"); 766 return; 767 } 768 if (logging) 769 strlcpy(curname, name, sizeof(curname)); 770 771 dochroot = (lc && login_getcapbool(lc, "ftp-chroot", 0)) || 772 checkuser(_PATH_FTPCHROOT, name); 773 if (anon_only && !dochroot) { 774 reply(530, "User %s access denied.", name); 775 return; 776 } 777 if (pw) { 778 if (pw->pw_uid < minuid) { 779 reply(530, "User %s access denied.", name); 780 if (logging) 781 syslog(LOG_NOTICE, 782 "FTP LOGIN REFUSED FROM %s, %s (UID))", 783 remotehost, name); 784 return; 785 } 786 if ((!shell && !dochroot) || checkuser(_PATH_FTPUSERS, name)) { 787 reply(530, "User %s access denied.", name); 788 if (logging) 789 syslog(LOG_NOTICE, 790 "FTP LOGIN REFUSED FROM %s, %s", 791 remotehost, name); 792 pw = NULL; 793 return; 794 } 795 } 796 797 if (as != NULL && (cp = auth_challenge(as)) != NULL) 798 reply(331, "%s", cp); 799 else 800 reply(331, "Password required for %s.", name); 801 802 askpasswd = 1; 803 /* 804 * Delay before reading passwd after first failed 805 * attempt to slow down passwd-guessing programs. 806 */ 807 if (login_attempts) 808 sleep((unsigned) login_attempts); 809} 810 811/* 812 * Check if a user is in the file "fname" 813 */ 814static int 815checkuser(char *fname, char *name) 816{ 817 FILE *fp; 818 int found = 0; 819 char *p, line[BUFSIZ]; 820 821 if ((fp = fopen(fname, "r")) != NULL) { 822 while (fgets(line, sizeof(line), fp) != NULL) 823 if ((p = strchr(line, '\n')) != NULL) { 824 *p = '\0'; 825 if (line[0] == '#') 826 continue; 827 if (strcmp(line, name) == 0) { 828 found = 1; 829 break; 830 } 831 } 832 (void) fclose(fp); 833 } 834 return (found); 835} 836 837/* 838 * Terminate login as previous user, if any, resetting state; 839 * used when USER command is given or login fails. 840 */ 841static void 842end_login(void) 843{ 844 sigprocmask (SIG_BLOCK, &allsigs, NULL); 845 if (logged_in) { 846 if (!nowtmp) 847 ftpdlogwtmp(ttyline, "", ""); 848 if (doutmp) 849 ftpd_logout(utmp.ut_line); 850 } 851 reply(530, "Please reconnect to work as another user"); 852 _exit(0); 853} 854 855enum auth_ret 856pass(char *passwd) 857{ 858 int authok; 859 unsigned int flags; 860 FILE *fp; 861 static char homedir[PATH_MAX]; 862 char *motd, *dir, rootdir[PATH_MAX]; 863 size_t sz_pw_dir; 864 865 if (logged_in || askpasswd == 0) { 866 reply(503, "Login with USER first."); 867 return (AUTH_FAILED); 868 } 869 askpasswd = 0; 870 if (!guest) { /* "ftp" is only account allowed no password */ 871 authok = 0; 872 if (pw == NULL || pw->pw_passwd[0] == '\0') { 873 useconds_t us; 874 875 /* Sleep between 1 and 3 seconds to emulate a crypt. */ 876 us = arc4random_uniform(3000000); 877 usleep(us); 878 if (as != NULL) { 879 auth_close(as); 880 as = NULL; 881 } 882 } else { 883 authok = auth_userresponse(as, passwd, 0); 884 as = NULL; 885 } 886 if (authok == 0) { 887 reply(530, "Login incorrect."); 888 if (logging) 889 syslog(LOG_NOTICE, 890 "FTP LOGIN FAILED FROM %s, %s", 891 remotehost, curname); 892 pw = NULL; 893 if (login_attempts++ >= 5) { 894 syslog(LOG_NOTICE, 895 "repeated login failures from %s", 896 remotehost); 897 kill_slave("repeated login failures"); 898 _exit(0); 899 } 900 return (AUTH_FAILED); 901 } 902 } else if (lc != NULL) { 903 /* Save anonymous' password. */ 904 free(guestpw); 905 guestpw = strdup(passwd); 906 if (guestpw == NULL) { 907 kill_slave("out of mem"); 908 fatal("Out of memory."); 909 } 910 911 authok = auth_approval(as, lc, pw->pw_name, "ftp"); 912 auth_close(as); 913 as = NULL; 914 if (authok == 0) { 915 syslog(LOG_INFO|LOG_AUTH, 916 "FTP LOGIN FAILED (HOST) as %s: approval failure.", 917 pw->pw_name); 918 reply(530, "Approval failure."); 919 kill_slave("approval failure"); 920 _exit(0); 921 } 922 } else { 923 syslog(LOG_INFO|LOG_AUTH, 924 "FTP LOGIN CLASS %s MISSING for %s: approval failure.", 925 pw->pw_class, pw->pw_name); 926 reply(530, "Permission denied."); 927 kill_slave("permission denied"); 928 _exit(0); 929 } 930 931 if (monitor_post_auth() == 1) { 932 /* Post-auth monitor process */ 933 logged_in = 1; 934 return (AUTH_MONITOR); 935 } 936 937 login_attempts = 0; /* this time successful */ 938 /* set umask via setusercontext() unless -u flag was given. */ 939 flags = LOGIN_SETGROUP|LOGIN_SETPRIORITY|LOGIN_SETRESOURCES; 940 if (umaskchange) 941 flags |= LOGIN_SETUMASK; 942 else 943 (void) umask(defumask); 944 if (setusercontext(lc, pw, 0, flags) != 0) { 945 perror_reply(421, "Local resource failure: setusercontext"); 946 syslog(LOG_NOTICE, "setusercontext: %m"); 947 dologout(1); 948 /* NOTREACHED */ 949 } 950 951 /* open wtmp before chroot */ 952 if (!nowtmp) 953 ftpdlogwtmp(ttyline, pw->pw_name, remotehost); 954 955 /* open utmp before chroot */ 956 if (doutmp) { 957 memset(&utmp, 0, sizeof(utmp)); 958 (void)time(&utmp.ut_time); 959 (void)strncpy(utmp.ut_name, pw->pw_name, sizeof(utmp.ut_name)); 960 (void)strncpy(utmp.ut_host, remotehost, sizeof(utmp.ut_host)); 961 (void)strncpy(utmp.ut_line, ttyline, sizeof(utmp.ut_line)); 962 ftpd_login(&utmp); 963 } 964 965 /* open stats file before chroot */ 966 if (guest && (stats == 1) && (statfd < 0)) 967 if ((statfd = open(_PATH_FTPDSTATFILE, O_WRONLY|O_APPEND)) < 0) 968 stats = 0; 969 970 logged_in = 1; 971 972 if ((dir = login_getcapstr(lc, "ftp-dir", NULL, NULL))) { 973 char *newdir; 974 975 newdir = copy_dir(dir, pw); 976 if (newdir == NULL) { 977 perror_reply(421, "Local resource failure: malloc"); 978 dologout(1); 979 /* NOTREACHED */ 980 } 981 pw->pw_dir = newdir; 982 pw = sgetpwnam(NULL, pw); 983 free(dir); 984 free(newdir); 985 } 986 987 /* make sure pw->pw_dir is big enough to hold "/" */ 988 sz_pw_dir = strlen(pw->pw_dir) + 1; 989 if (sz_pw_dir < 2) { 990 pw->pw_dir = "/"; 991 pw = sgetpwnam(NULL, pw); 992 sz_pw_dir = 2; 993 } 994 995 if (guest || dochroot) { 996 if (multihome && guest) { 997 struct stat ts; 998 999 /* Compute root directory. */ 1000 snprintf(rootdir, sizeof(rootdir), "%s/%s", 1001 pw->pw_dir, dhostname); 1002 if (stat(rootdir, &ts) < 0) { 1003 snprintf(rootdir, sizeof(rootdir), "%s/%s", 1004 pw->pw_dir, hostname); 1005 } 1006 } else 1007 strlcpy(rootdir, pw->pw_dir, sizeof(rootdir)); 1008 } 1009 if (guest) { 1010 /* 1011 * We MUST do a chdir() after the chroot. Otherwise 1012 * the old current directory will be accessible as "." 1013 * outside the new root! 1014 */ 1015 if (chroot(rootdir) < 0 || chdir("/") < 0) { 1016 reply(550, "Can't set guest privileges."); 1017 goto bad; 1018 } 1019 strlcpy(pw->pw_dir, "/", sz_pw_dir); 1020 if (setenv("HOME", "/", 1) == -1) { 1021 reply(550, "Can't setup environment."); 1022 goto bad; 1023 } 1024 } else if (dochroot) { 1025 if (chroot(rootdir) < 0 || chdir("/") < 0) { 1026 reply(550, "Can't change root."); 1027 goto bad; 1028 } 1029 strlcpy(pw->pw_dir, "/", sz_pw_dir); 1030 if (setenv("HOME", "/", 1) == -1) { 1031 reply(550, "Can't setup environment."); 1032 goto bad; 1033 } 1034 } else if (chdir(pw->pw_dir) < 0) { 1035 if (chdir("/") < 0) { 1036 reply(530, "User %s: can't change directory to %s.", 1037 pw->pw_name, pw->pw_dir); 1038 goto bad; 1039 } else 1040 lreply(230, "No directory! Logging in with home=/"); 1041 } 1042 if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0) { 1043 reply(550, "Can't set gid."); 1044 goto bad; 1045 } 1046 if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0) { 1047 reply(550, "Can't set uid."); 1048 goto bad; 1049 } 1050 sigprocmask(SIG_UNBLOCK, &allsigs, NULL); 1051 1052 /* 1053 * Set home directory so that use of ~ (tilde) works correctly. 1054 */ 1055 if (getcwd(homedir, PATH_MAX) != NULL) { 1056 if (setenv("HOME", homedir, 1) == -1) { 1057 reply(550, "Can't setup environment."); 1058 goto bad; 1059 } 1060 } 1061 1062 /* 1063 * Display a login message, if it exists. 1064 * N.B. reply(230,) must follow the message. 1065 */ 1066 motd = login_getcapstr(lc, "welcome", NULL, NULL); 1067 if ((fp = fopen(motd ? motd : _PATH_FTPLOGINMESG, "r")) != NULL) { 1068 char line[LINE_MAX]; 1069 1070 while (fgets(line, sizeof(line), fp) != NULL) { 1071 line[strcspn(line, "\n")] = '\0'; 1072 lreply(230, "%s", line); 1073 } 1074 (void) fflush(stdout); 1075 (void) fclose(fp); 1076 } 1077 free(motd); 1078 if (guest) { 1079 reply(230, "Guest login ok, access restrictions apply."); 1080 snprintf(proctitle, sizeof(proctitle), 1081 "%s: anonymous/%.*s", remotehost, 1082 (int)(sizeof(proctitle) - sizeof(remotehost) - 1083 sizeof(": anonymous/")), passwd); 1084 setproctitle("%s", proctitle); 1085 if (logging) 1086 syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s, %s", 1087 remotehost, passwd); 1088 } else { 1089 reply(230, "User %s logged in.", pw->pw_name); 1090 snprintf(proctitle, sizeof(proctitle), 1091 "%s: %s", remotehost, pw->pw_name); 1092 setproctitle("%s", proctitle); 1093 if (logging) 1094 syslog(LOG_INFO, "FTP LOGIN FROM %s as %s", 1095 remotehost, pw->pw_name); 1096 } 1097 login_close(lc); 1098 lc = NULL; 1099 return (AUTH_SLAVE); 1100bad: 1101 /* Forget all about it... */ 1102 login_close(lc); 1103 lc = NULL; 1104 end_login(); 1105 return (AUTH_FAILED); 1106} 1107 1108void 1109retrieve(char *cmd, char *name) 1110{ 1111 FILE *fin, *dout; 1112 struct stat st; 1113 pid_t pid; 1114 time_t start; 1115 1116 if (cmd == NULL) { 1117 fin = fopen(name, "r"); 1118 st.st_size = 0; 1119 } else { 1120 char line[BUFSIZ]; 1121 1122 (void) snprintf(line, sizeof(line), cmd, name); 1123 name = line; 1124 fin = ftpd_popen(line, "r", &pid); 1125 st.st_size = -1; 1126 st.st_blksize = BUFSIZ; 1127 } 1128 if (fin == NULL) { 1129 if (errno != 0) { 1130 perror_reply(550, name); 1131 if (cmd == NULL) { 1132 LOGCMD("get", name); 1133 } 1134 } 1135 return; 1136 } 1137 byte_count = -1; 1138 if (cmd == NULL && 1139 (fstat(fileno(fin), &st) < 0 || !S_ISREG(st.st_mode))) { 1140 reply(550, "%s: not a plain file.", name); 1141 goto done; 1142 } 1143 if (restart_point) { 1144 if (type == TYPE_A) { 1145 off_t i, n; 1146 int c; 1147 1148 n = restart_point; 1149 i = 0; 1150 while (i++ < n) { 1151 if ((c = getc(fin)) == EOF) { 1152 if (ferror(fin)) { 1153 perror_reply(550, name); 1154 goto done; 1155 } else 1156 break; 1157 } 1158 if (c == '\n') 1159 i++; 1160 } 1161 } else if (lseek(fileno(fin), restart_point, SEEK_SET) < 0) { 1162 perror_reply(550, name); 1163 goto done; 1164 } 1165 } 1166 dout = dataconn(name, st.st_size, "w"); 1167 if (dout == NULL) 1168 goto done; 1169 time(&start); 1170 send_data(fin, dout, st.st_blksize, st.st_size, 1171 (restart_point == 0 && cmd == NULL && S_ISREG(st.st_mode))); 1172 if ((cmd == NULL) && stats) 1173 logxfer(name, byte_count, start); 1174 (void) fclose(dout); 1175 data = -1; 1176done: 1177 if (pdata >= 0) 1178 (void) close(pdata); 1179 pdata = -1; 1180 if (cmd == NULL) { 1181 LOGBYTES("get", name, byte_count); 1182 fclose(fin); 1183 } else { 1184 ftpd_pclose(fin, pid); 1185 } 1186} 1187 1188void 1189store(char *name, char *mode, int unique) 1190{ 1191 FILE *fout, *din; 1192 int (*closefunc)(FILE *); 1193 struct stat st; 1194 int fd; 1195 1196 if (restart_point && *mode != 'a') 1197 mode = "r+"; 1198 1199 if (unique && stat(name, &st) == 0) { 1200 char *nam; 1201 1202 fd = guniquefd(name, &nam); 1203 if (fd == -1) { 1204 LOGCMD(*mode == 'w' ? "put" : "append", name); 1205 return; 1206 } 1207 name = nam; 1208 fout = fdopen(fd, mode); 1209 } else 1210 fout = fopen(name, mode); 1211 1212 closefunc = fclose; 1213 if (fout == NULL) { 1214 perror_reply(553, name); 1215 LOGCMD(*mode == 'w' ? "put" : "append", name); 1216 return; 1217 } 1218 byte_count = -1; 1219 if (restart_point) { 1220 if (type == TYPE_A) { 1221 off_t i, n; 1222 int c; 1223 1224 n = restart_point; 1225 i = 0; 1226 while (i++ < n) { 1227 if ((c = getc(fout)) == EOF) { 1228 if (ferror(fout)) { 1229 perror_reply(550, name); 1230 goto done; 1231 } else 1232 break; 1233 } 1234 if (c == '\n') 1235 i++; 1236 } 1237 /* 1238 * We must do this seek to "current" position 1239 * because we are changing from reading to 1240 * writing. 1241 */ 1242 if (fseek(fout, 0, SEEK_CUR) < 0) { 1243 perror_reply(550, name); 1244 goto done; 1245 } 1246 } else if (lseek(fileno(fout), restart_point, SEEK_SET) < 0) { 1247 perror_reply(550, name); 1248 goto done; 1249 } 1250 } 1251 din = dataconn(name, -1, "r"); 1252 if (din == NULL) 1253 goto done; 1254 if (receive_data(din, fout) == 0) { 1255 if (unique) 1256 reply(226, "Transfer complete (unique file name:%s).", 1257 name); 1258 else 1259 reply(226, "Transfer complete."); 1260 } 1261 (void) fclose(din); 1262 data = -1; 1263 pdata = -1; 1264done: 1265 LOGBYTES(*mode == 'w' ? "put" : "append", name, byte_count); 1266 (*closefunc)(fout); 1267} 1268 1269static FILE * 1270getdatasock(char *mode) 1271{ 1272 int on = 1, s, t, tries; 1273 1274 if (data >= 0) 1275 return (fdopen(data, mode)); 1276 sigprocmask (SIG_BLOCK, &allsigs, NULL); 1277 s = monitor_socket(ctrl_addr.su_family); 1278 if (s < 0) 1279 goto bad; 1280 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, 1281 &on, sizeof(on)) < 0) 1282 goto bad; 1283 /* anchor socket to avoid multi-homing problems */ 1284 data_source = ctrl_addr; 1285 data_source.su_port = htons(20); /* ftp-data port */ 1286 for (tries = 1; ; tries++) { 1287 if (monitor_bind(s, (struct sockaddr *)&data_source, 1288 data_source.su_len) >= 0) 1289 break; 1290 if (errno != EADDRINUSE || tries > 10) 1291 goto bad; 1292 sleep((unsigned int)tries); 1293 } 1294 sigprocmask (SIG_UNBLOCK, &allsigs, NULL); 1295 1296 if (ctrl_addr.su_family == AF_INET) { 1297 on = IPTOS_THROUGHPUT; 1298 if (setsockopt(s, IPPROTO_IP, IP_TOS, &on, 1299 sizeof(int)) < 0) 1300 syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); 1301 } 1302 /* 1303 * Turn off push flag to keep sender TCP from sending short packets 1304 * at the boundaries of each write(). Should probably do a SO_SNDBUF 1305 * to set the send buffer size as well, but that may not be desirable 1306 * in heavy-load situations. 1307 */ 1308 on = 1; 1309 if (setsockopt(s, IPPROTO_TCP, TCP_NOPUSH, &on, sizeof(on)) < 0) 1310 syslog(LOG_WARNING, "setsockopt (TCP_NOPUSH): %m"); 1311 on = 65536; 1312 if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &on, sizeof(on)) < 0) 1313 syslog(LOG_WARNING, "setsockopt (SO_SNDBUF): %m"); 1314 1315 return (fdopen(s, mode)); 1316bad: 1317 /* Return the real value of errno (close may change it) */ 1318 t = errno; 1319 sigprocmask (SIG_UNBLOCK, &allsigs, NULL); 1320 if (s >= 0) 1321 (void) close(s); 1322 errno = t; 1323 return (NULL); 1324} 1325 1326static FILE * 1327dataconn(char *name, off_t size, char *mode) 1328{ 1329 char sizebuf[32]; 1330 FILE *file = NULL; 1331 int retry = 0; 1332 in_port_t *p; 1333 u_char *fa, *ha; 1334 size_t alen; 1335 int error; 1336 1337 file_size = size; 1338 byte_count = 0; 1339 if (size != -1) { 1340 (void) snprintf(sizebuf, sizeof(sizebuf), " (%lld bytes)", 1341 (long long)size); 1342 } else 1343 sizebuf[0] = '\0'; 1344 if (pdata >= 0) { 1345 union sockunion from; 1346 int s; 1347 socklen_t fromlen = sizeof(from); 1348 1349 (void) alarm ((unsigned) timeout); 1350 s = accept(pdata, (struct sockaddr *)&from, &fromlen); 1351 (void) alarm (0); 1352 if (s < 0) { 1353 reply(425, "Can't open data connection."); 1354 (void) close(pdata); 1355 pdata = -1; 1356 return (NULL); 1357 } 1358 switch (from.su_family) { 1359 case AF_INET: 1360 p = (in_port_t *)&from.su_sin.sin_port; 1361 fa = (u_char *)&from.su_sin.sin_addr; 1362 ha = (u_char *)&his_addr.su_sin.sin_addr; 1363 alen = sizeof(struct in_addr); 1364 break; 1365 case AF_INET6: 1366 p = (in_port_t *)&from.su_sin6.sin6_port; 1367 fa = (u_char *)&from.su_sin6.sin6_addr; 1368 ha = (u_char *)&his_addr.su_sin6.sin6_addr; 1369 alen = sizeof(struct in6_addr); 1370 break; 1371 default: 1372 reply(425, "Can't build data connection: " 1373 "unknown address family"); 1374 (void) close(pdata); 1375 (void) close(s); 1376 pdata = -1; 1377 return (NULL); 1378 } 1379 if (from.su_family != his_addr.su_family || 1380 ntohs(*p) < IPPORT_RESERVED) { 1381 reply(425, "Can't build data connection: " 1382 "address family or port error"); 1383 (void) close(pdata); 1384 (void) close(s); 1385 pdata = -1; 1386 return (NULL); 1387 } 1388 if (portcheck && memcmp(fa, ha, alen) != 0) { 1389 reply(425, "Can't build data connection: " 1390 "illegal port number"); 1391 (void) close(pdata); 1392 (void) close(s); 1393 pdata = -1; 1394 return (NULL); 1395 } 1396 (void) close(pdata); 1397 pdata = s; 1398 reply(150, "Opening %s mode data connection for '%s'%s.", 1399 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); 1400 return (fdopen(pdata, mode)); 1401 } 1402 if (data >= 0) { 1403 reply(125, "Using existing data connection for '%s'%s.", 1404 name, sizebuf); 1405 usedefault = 1; 1406 return (fdopen(data, mode)); 1407 } 1408 if (usedefault) 1409 data_dest = his_addr; 1410 usedefault = 1; 1411 do { 1412 if (file != NULL) 1413 (void) fclose(file); 1414 file = getdatasock(mode); 1415 if (file == NULL) { 1416 char hbuf[HOST_NAME_MAX+1], pbuf[10]; 1417 1418 error = getnameinfo((struct sockaddr *)&data_source, 1419 data_source.su_len, hbuf, sizeof(hbuf), pbuf, 1420 sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV); 1421 if (error != 0) 1422 reply(425, "Can't create data socket: %s.", 1423 strerror(errno)); 1424 else 1425 reply(425, 1426 "Can't create data socket (%s,%s): %s.", 1427 hbuf, pbuf, strerror(errno)); 1428 return (NULL); 1429 } 1430 1431 /* 1432 * attempt to connect to reserved port on client machine; 1433 * this looks like an attack 1434 */ 1435 switch (data_dest.su_family) { 1436 case AF_INET: 1437 p = (in_port_t *)&data_dest.su_sin.sin_port; 1438 fa = (u_char *)&data_dest.su_sin.sin_addr; 1439 ha = (u_char *)&his_addr.su_sin.sin_addr; 1440 alen = sizeof(struct in_addr); 1441 break; 1442 case AF_INET6: 1443 p = (in_port_t *)&data_dest.su_sin6.sin6_port; 1444 fa = (u_char *)&data_dest.su_sin6.sin6_addr; 1445 ha = (u_char *)&his_addr.su_sin6.sin6_addr; 1446 alen = sizeof(struct in6_addr); 1447 break; 1448 default: 1449 reply(425, "Can't build data connection: " 1450 "unknown address family"); 1451 (void) fclose(file); 1452 pdata = -1; 1453 return (NULL); 1454 } 1455 if (data_dest.su_family != his_addr.su_family || 1456 ntohs(*p) < IPPORT_RESERVED || ntohs(*p) == 2049) { /* XXX */ 1457 reply(425, "Can't build data connection: " 1458 "address family or port error"); 1459 (void) fclose(file); 1460 return NULL; 1461 } 1462 if (portcheck && memcmp(fa, ha, alen) != 0) { 1463 reply(435, "Can't build data connection: " 1464 "illegal port number"); 1465 (void) fclose(file); 1466 return NULL; 1467 } 1468 1469 if (connect(fileno(file), (struct sockaddr *)&data_dest, 1470 data_dest.su_len) == 0) { 1471 reply(150, "Opening %s mode data connection for '%s'%s.", 1472 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); 1473 data = fileno(file); 1474 return (file); 1475 } 1476 if (errno != EADDRINUSE) 1477 break; 1478 sleep((unsigned) swaitint); 1479 retry += swaitint; 1480 } while (retry <= swaitmax); 1481 perror_reply(425, "Can't build data connection"); 1482 (void) fclose(file); 1483 return (NULL); 1484} 1485 1486/* 1487 * Transfer the contents of "instr" to "outstr" peer using the appropriate 1488 * encapsulation of the data subject to Mode, Structure, and Type. 1489 * 1490 * NB: Form isn't handled. 1491 */ 1492static int 1493send_data(FILE *instr, FILE *outstr, off_t blksize, off_t filesize, int isreg) 1494{ 1495 int c, cnt, filefd, netfd; 1496 char *buf, *bp; 1497 size_t len; 1498 1499 transflag++; 1500 switch (type) { 1501 1502 case TYPE_A: 1503 while ((c = getc(instr)) != EOF) { 1504 if (recvurg) 1505 goto got_oob; 1506 byte_count++; 1507 if (c == '\n') { 1508 if (ferror(outstr)) 1509 goto data_err; 1510 (void) putc('\r', outstr); 1511 } 1512 (void) putc(c, outstr); 1513 } 1514 fflush(outstr); 1515 transflag = 0; 1516 if (ferror(instr)) 1517 goto file_err; 1518 if (ferror(outstr)) 1519 goto data_err; 1520 reply(226, "Transfer complete."); 1521 return(0); 1522 1523 case TYPE_I: 1524 case TYPE_L: 1525 /* 1526 * isreg is only set if we are not doing restart and we 1527 * are sending a regular file 1528 */ 1529 netfd = fileno(outstr); 1530 filefd = fileno(instr); 1531 1532 if (isreg && filesize < 16 * 1024 * 1024) { 1533 size_t fsize = (size_t)filesize; 1534 1535 if (fsize == 0) { 1536 transflag = 0; 1537 reply(226, "Transfer complete."); 1538 return(0); 1539 } 1540 1541 buf = mmap(0, fsize, PROT_READ, MAP_SHARED, filefd, 0); 1542 if (buf == MAP_FAILED) { 1543 syslog(LOG_WARNING, "mmap(%llu): %m", 1544 (unsigned long long)fsize); 1545 goto oldway; 1546 } 1547 bp = buf; 1548 len = fsize; 1549 do { 1550 cnt = write(netfd, bp, len); 1551 if (recvurg) { 1552 munmap(buf, fsize); 1553 goto got_oob; 1554 } 1555 len -= cnt; 1556 bp += cnt; 1557 if (cnt > 0) 1558 byte_count += cnt; 1559 } while(cnt > 0 && len > 0); 1560 1561 transflag = 0; 1562 munmap(buf, fsize); 1563 if (cnt < 0) 1564 goto data_err; 1565 reply(226, "Transfer complete."); 1566 return(0); 1567 } 1568 1569oldway: 1570 if ((buf = malloc((size_t)blksize)) == NULL) { 1571 transflag = 0; 1572 perror_reply(451, "Local resource failure: malloc"); 1573 return(-1); 1574 } 1575 1576 while ((cnt = read(filefd, buf, (size_t)blksize)) > 0 && 1577 write(netfd, buf, cnt) == cnt) 1578 byte_count += cnt; 1579 transflag = 0; 1580 (void)free(buf); 1581 if (cnt != 0) { 1582 if (cnt < 0) 1583 goto file_err; 1584 goto data_err; 1585 } 1586 reply(226, "Transfer complete."); 1587 return(0); 1588 default: 1589 transflag = 0; 1590 reply(550, "Unimplemented TYPE %d in send_data", type); 1591 return(-1); 1592 } 1593 1594data_err: 1595 transflag = 0; 1596 reply(426, "Data connection"); 1597 return(-1); 1598 1599file_err: 1600 transflag = 0; 1601 reply(551, "Error on input file"); 1602 return(-1); 1603 1604got_oob: 1605 myoob(); 1606 recvurg = 0; 1607 transflag = 0; 1608 return(-1); 1609} 1610 1611/* 1612 * Transfer data from peer to "outstr" using the appropriate encapulation of 1613 * the data subject to Mode, Structure, and Type. 1614 * 1615 * N.B.: Form isn't handled. 1616 */ 1617static int 1618receive_data(FILE *instr, FILE *outstr) 1619{ 1620 int c; 1621 int cnt; 1622 char buf[BUFSIZ]; 1623 struct sigaction sa, sa_saved; 1624 volatile int bare_lfs = 0; 1625 1626 transflag++; 1627 switch (type) { 1628 1629 case TYPE_I: 1630 case TYPE_L: 1631 memset(&sa, 0, sizeof(sa)); 1632 sigfillset(&sa.sa_mask); 1633 sa.sa_flags = SA_RESTART; 1634 sa.sa_handler = lostconn; 1635 (void) sigaction(SIGALRM, &sa, &sa_saved); 1636 do { 1637 (void) alarm ((unsigned) timeout); 1638 cnt = read(fileno(instr), buf, sizeof(buf)); 1639 (void) alarm (0); 1640 if (recvurg) 1641 goto got_oob; 1642 1643 if (cnt > 0) { 1644 if (write(fileno(outstr), buf, cnt) != cnt) 1645 goto file_err; 1646 byte_count += cnt; 1647 } 1648 } while (cnt > 0); 1649 (void) sigaction(SIGALRM, &sa_saved, NULL); 1650 if (cnt < 0) 1651 goto data_err; 1652 transflag = 0; 1653 return (0); 1654 1655 case TYPE_E: 1656 reply(553, "TYPE E not implemented."); 1657 transflag = 0; 1658 return (-1); 1659 1660 case TYPE_A: 1661 while ((c = getc(instr)) != EOF) { 1662 if (recvurg) 1663 goto got_oob; 1664 byte_count++; 1665 if (c == '\n') 1666 bare_lfs++; 1667 while (c == '\r') { 1668 if (ferror(outstr)) 1669 goto data_err; 1670 if ((c = getc(instr)) != '\n') { 1671 (void) putc ('\r', outstr); 1672 if (c == '\0' || c == EOF) 1673 goto contin2; 1674 } 1675 } 1676 (void) putc(c, outstr); 1677 contin2: ; 1678 } 1679 fflush(outstr); 1680 if (ferror(instr)) 1681 goto data_err; 1682 if (ferror(outstr)) 1683 goto file_err; 1684 transflag = 0; 1685 if (bare_lfs) { 1686 lreply(226, 1687 "WARNING! %d bare linefeeds received in ASCII mode", 1688 bare_lfs); 1689 printf(" File may not have transferred correctly.\r\n"); 1690 } 1691 return (0); 1692 default: 1693 reply(550, "Unimplemented TYPE %d in receive_data", type); 1694 transflag = 0; 1695 return (-1); 1696 } 1697 1698data_err: 1699 transflag = 0; 1700 reply(426, "Data Connection"); 1701 return (-1); 1702 1703file_err: 1704 transflag = 0; 1705 reply(452, "Error writing file"); 1706 return (-1); 1707 1708got_oob: 1709 myoob(); 1710 recvurg = 0; 1711 transflag = 0; 1712 return (-1); 1713} 1714 1715void 1716statfilecmd(char *filename) 1717{ 1718 FILE *fin; 1719 int c; 1720 int atstart; 1721 pid_t pid; 1722 char line[LINE_MAX]; 1723 1724 (void)snprintf(line, sizeof(line), "/bin/ls -lgA %s", filename); 1725 fin = ftpd_popen(line, "r", &pid); 1726 if (fin == NULL) { 1727 reply(451, "Local resource failure"); 1728 return; 1729 } 1730 lreply(211, "status of %s:", filename); 1731 atstart = 1; 1732 while ((c = getc(fin)) != EOF) { 1733 if (c == '\n') { 1734 if (ferror(stdout)){ 1735 perror_reply(421, "control connection"); 1736 (void) ftpd_pclose(fin, pid); 1737 dologout(1); 1738 /* NOTREACHED */ 1739 } 1740 if (ferror(fin)) { 1741 perror_reply(551, filename); 1742 (void) ftpd_pclose(fin, pid); 1743 return; 1744 } 1745 (void) putc('\r', stdout); 1746 } 1747 if (atstart && isdigit(c)) 1748 (void) putc(' ', stdout); 1749 (void) putc(c, stdout); 1750 atstart = (c == '\n'); 1751 } 1752 (void) ftpd_pclose(fin, pid); 1753 reply(211, "End of Status"); 1754} 1755 1756void 1757statcmd(void) 1758{ 1759 union sockunion *su; 1760 u_char *a, *p; 1761 char hbuf[HOST_NAME_MAX+1]; 1762 int ispassive; 1763 int error; 1764 1765 lreply(211, "%s FTP server status:", hostname); 1766 error = getnameinfo((struct sockaddr *)&his_addr, his_addr.su_len, 1767 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST); 1768 printf(" Connected to %s", remotehost); 1769 if (error == 0 && strcmp(remotehost, hbuf) != 0) 1770 printf(" (%s)", hbuf); 1771 printf("\r\n"); 1772 if (logged_in) { 1773 if (guest) 1774 printf(" Logged in anonymously\r\n"); 1775 else 1776 printf(" Logged in as %s\r\n", pw->pw_name); 1777 } else if (askpasswd) 1778 printf(" Waiting for password\r\n"); 1779 else 1780 printf(" Waiting for user name\r\n"); 1781 printf(" TYPE: %s", typenames[type]); 1782 if (type == TYPE_A || type == TYPE_E) 1783 printf(", FORM: %s", formnames[form]); 1784 if (type == TYPE_L) 1785 printf(" 8"); 1786 printf("; STRUcture: %s; transfer MODE: %s\r\n", 1787 strunames[stru], modenames[mode]); 1788 ispassive = 0; 1789 if (data != -1) 1790 printf(" Data connection open\r\n"); 1791 else if (pdata != -1) { 1792 printf(" in Passive mode\r\n"); 1793 su = (union sockunion *)&pasv_addr; 1794 ispassive++; 1795 goto printaddr; 1796 } else if (usedefault == 0) { 1797 size_t alen; 1798 int af, i; 1799 1800 su = (union sockunion *)&data_dest; 1801printaddr: 1802 /* PASV/PORT */ 1803 if (su->su_family == AF_INET) { 1804 if (ispassive) 1805 printf("211- PASV "); 1806 else 1807 printf("211- PORT "); 1808 a = (u_char *)&su->su_sin.sin_addr; 1809 p = (u_char *)&su->su_sin.sin_port; 1810 printf("(%u,%u,%u,%u,%u,%u)\r\n", 1811 a[0], a[1], a[2], a[3], 1812 p[0], p[1]); 1813 } 1814 1815 /* LPSV/LPRT */ 1816 alen = 0; 1817 switch (su->su_family) { 1818 case AF_INET: 1819 a = (u_char *)&su->su_sin.sin_addr; 1820 p = (u_char *)&su->su_sin.sin_port; 1821 alen = sizeof(su->su_sin.sin_addr); 1822 af = 4; 1823 break; 1824 case AF_INET6: 1825 a = (u_char *)&su->su_sin6.sin6_addr; 1826 p = (u_char *)&su->su_sin6.sin6_port; 1827 alen = sizeof(su->su_sin6.sin6_addr); 1828 af = 6; 1829 break; 1830 default: 1831 af = 0; 1832 break; 1833 } 1834 if (af) { 1835 if (ispassive) 1836 printf("211- LPSV "); 1837 else 1838 printf("211- LPRT "); 1839 printf("(%u,%llu", af, (unsigned long long)alen); 1840 for (i = 0; i < alen; i++) 1841 printf(",%u", a[i]); 1842 printf(",%u,%u,%u)\r\n", 2, p[0], p[1]); 1843 } 1844 1845 /* EPRT/EPSV */ 1846 switch (su->su_family) { 1847 case AF_INET: 1848 af = 1; 1849 break; 1850 case AF_INET6: 1851 af = 2; 1852 break; 1853 default: 1854 af = 0; 1855 break; 1856 } 1857 if (af) { 1858 char pbuf[10]; 1859 union sockunion tmp = *su; 1860 1861 if (tmp.su_family == AF_INET6) 1862 tmp.su_sin6.sin6_scope_id = 0; 1863 if (getnameinfo((struct sockaddr *)&tmp, tmp.su_len, 1864 hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), 1865 NI_NUMERICHOST | NI_NUMERICSERV) == 0) { 1866 if (ispassive) 1867 printf("211- EPSV "); 1868 else 1869 printf("211- EPRT "); 1870 printf("(|%u|%s|%s|)\r\n", 1871 af, hbuf, pbuf); 1872 } 1873 } 1874 } else 1875 printf(" No data connection\r\n"); 1876 reply(211, "End of status"); 1877} 1878 1879void 1880fatal(char *s) 1881{ 1882 1883 reply(451, "Error in server: %s", s); 1884 reply(221, "Closing connection due to server error."); 1885 dologout(0); 1886 /* NOTREACHED */ 1887} 1888 1889void 1890reply(int n, const char *fmt, ...) 1891{ 1892 char *buf, *p, *next; 1893 int rval; 1894 va_list ap; 1895 1896 va_start(ap, fmt); 1897 rval = vasprintf(&buf, fmt, ap); 1898 va_end(ap); 1899 if (rval == -1 || buf == NULL) { 1900 printf("421 Local resource failure: malloc\r\n"); 1901 fflush(stdout); 1902 dologout(1); 1903 } 1904 next = buf; 1905 while ((p = strsep(&next, "\n\r"))) { 1906 printf("%d%s %s\r\n", n, (next != NULL) ? "-" : "", p); 1907 if (debug) 1908 syslog(LOG_DEBUG, "<--- %d%s %s", n, 1909 (next != NULL) ? "-" : "", p); 1910 } 1911 (void)fflush(stdout); 1912 free(buf); 1913} 1914 1915 1916void 1917reply_r(int n, const char *fmt, ...) 1918{ 1919 char *p, *next; 1920 char msg[BUFSIZ]; 1921 char buf[BUFSIZ]; 1922 va_list ap; 1923 struct syslog_data sdata = SYSLOG_DATA_INIT; 1924 1925 sdata.log_fac = LOG_FTP; 1926 va_start(ap, fmt); 1927 vsnprintf(msg, sizeof(msg), fmt, ap); 1928 va_end(ap); 1929 1930 next = msg; 1931 1932 while ((p = strsep(&next, "\n\r"))) { 1933 snprintf(buf, sizeof(buf), "%d%s %s\r\n", n, 1934 (next != NULL) ? "-" : "", p); 1935 write(STDOUT_FILENO, buf, strlen(buf)); 1936 if (debug) { 1937 buf[strlen(buf) - 2] = '\0'; 1938 syslog_r(LOG_DEBUG, &sdata, "<--- %s", buf); 1939 } 1940 } 1941} 1942 1943void 1944lreply(int n, const char *fmt, ...) 1945{ 1946 va_list ap; 1947 1948 va_start(ap, fmt); 1949 (void)printf("%d- ", n); 1950 (void)vprintf(fmt, ap); 1951 va_end(ap); 1952 (void)printf("\r\n"); 1953 (void)fflush(stdout); 1954 if (debug) { 1955 va_start(ap, fmt); 1956 syslog(LOG_DEBUG, "<--- %d- ", n); 1957 vsyslog(LOG_DEBUG, fmt, ap); 1958 va_end(ap); 1959 } 1960} 1961 1962static void 1963ack(char *s) 1964{ 1965 1966 reply(250, "%s command successful.", s); 1967} 1968 1969void 1970nack(char *s) 1971{ 1972 1973 reply(502, "%s command not implemented.", s); 1974} 1975 1976/* ARGSUSED */ 1977void 1978yyerror(char *s) 1979{ 1980 cbuf[strcspn(cbuf, "\n")] = '\0'; 1981 reply(500, "'%s': command not understood.", cbuf); 1982} 1983 1984void 1985delete(char *name) 1986{ 1987 struct stat st; 1988 1989 LOGCMD("delete", name); 1990 if (stat(name, &st) < 0) { 1991 perror_reply(550, name); 1992 return; 1993 } 1994 if ((st.st_mode&S_IFMT) == S_IFDIR) { 1995 if (rmdir(name) < 0) { 1996 perror_reply(550, name); 1997 return; 1998 } 1999 goto done; 2000 } 2001 if (unlink(name) < 0) { 2002 perror_reply(550, name); 2003 return; 2004 } 2005done: 2006 ack("DELE"); 2007} 2008 2009void 2010cwd(char *path) 2011{ 2012 FILE *message; 2013 2014 if (chdir(path) < 0) 2015 perror_reply(550, path); 2016 else { 2017 if ((message = fopen(_PATH_CWDMESG, "r")) != NULL) { 2018 char line[LINE_MAX]; 2019 2020 while (fgets(line, sizeof(line), message) != NULL) { 2021 line[strcspn(line, "\n")] = '\0'; 2022 lreply(250, "%s", line); 2023 } 2024 (void) fflush(stdout); 2025 (void) fclose(message); 2026 } 2027 ack("CWD"); 2028 } 2029} 2030 2031void 2032replydirname(const char *name, const char *message) 2033{ 2034 char *p, *ep; 2035 char npath[PATH_MAX * 2]; 2036 2037 p = npath; 2038 ep = &npath[sizeof(npath) - 1]; 2039 while (*name) { 2040 if (*name == '"') { 2041 if (ep - p < 2) 2042 break; 2043 *p++ = *name++; 2044 *p++ = '"'; 2045 } else { 2046 if (ep - p < 1) 2047 break; 2048 *p++ = *name++; 2049 } 2050 } 2051 *p = '\0'; 2052 reply(257, "\"%s\" %s", npath, message); 2053} 2054 2055void 2056makedir(char *name) 2057{ 2058 2059 LOGCMD("mkdir", name); 2060 if (mkdir(name, 0777) < 0) 2061 perror_reply(550, name); 2062 else 2063 replydirname(name, "directory created."); 2064} 2065 2066void 2067removedir(char *name) 2068{ 2069 2070 LOGCMD("rmdir", name); 2071 if (rmdir(name) < 0) 2072 perror_reply(550, name); 2073 else 2074 ack("RMD"); 2075} 2076 2077void 2078pwd(void) 2079{ 2080 char path[PATH_MAX]; 2081 2082 if (getcwd(path, sizeof(path)) == NULL) 2083 perror_reply(550, "Can't get current directory"); 2084 else 2085 replydirname(path, "is current directory."); 2086} 2087 2088char * 2089renamefrom(char *name) 2090{ 2091 struct stat st; 2092 2093 if (stat(name, &st) < 0) { 2094 perror_reply(550, name); 2095 return (NULL); 2096 } 2097 reply(350, "File exists, ready for destination name"); 2098 return (name); 2099} 2100 2101void 2102renamecmd(char *from, char *to) 2103{ 2104 2105 LOGCMD2("rename", from, to); 2106 if (rename(from, to) < 0) 2107 perror_reply(550, "rename"); 2108 else 2109 ack("RNTO"); 2110} 2111 2112static void 2113dolog(struct sockaddr *sa) 2114{ 2115 char hbuf[sizeof(remotehost)]; 2116 2117 if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0, 0) == 0) 2118 (void) strlcpy(remotehost, hbuf, sizeof(remotehost)); 2119 else 2120 (void) strlcpy(remotehost, "unknown", sizeof(remotehost)); 2121 2122 snprintf(proctitle, sizeof(proctitle), "%s: connected", remotehost); 2123 setproctitle("%s", proctitle); 2124 2125 if (logging) { 2126 int error; 2127 error = getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), 2128 NULL, 0, NI_NUMERICHOST); 2129 syslog(LOG_INFO, "connection from %s [%s]", remotehost, 2130 error ? gai_strerror(error) : hbuf); 2131 } 2132} 2133 2134/* 2135 * Record logout in wtmp file and exit with supplied status. 2136 * NOTE: because this is called from signal handlers it cannot 2137 * use stdio (or call other functions that use stdio). 2138 */ 2139void 2140dologout(int status) 2141{ 2142 2143 transflag = 0; 2144 2145 if (logged_in) { 2146 sigprocmask(SIG_BLOCK, &allsigs, NULL); 2147 if (!nowtmp) 2148 ftpdlogwtmp(ttyline, "", ""); 2149 if (doutmp) 2150 ftpd_logout(utmp.ut_line); 2151 } 2152 /* beware of flushing buffers after a SIGPIPE */ 2153 _exit(status); 2154} 2155 2156/*ARGSUSED*/ 2157static void 2158sigurg(int signo) 2159{ 2160 2161 recvurg = 1; 2162} 2163 2164static void 2165myoob(void) 2166{ 2167 char *cp; 2168 int ret; 2169 2170 /* only process if transfer occurring */ 2171 if (!transflag) 2172 return; 2173 cp = tmpline; 2174 ret = get_line(cp, sizeof(tmpline)-1, stdin); 2175 if (ret == -1) { 2176 reply(221, "You could at least say goodbye."); 2177 dologout(0); 2178 } else if (ret == -2) { 2179 /* Ignore truncated command */ 2180 return; 2181 } 2182 upper(cp); 2183 if (strcmp(cp, "ABOR\r\n") == 0) { 2184 tmpline[0] = '\0'; 2185 reply(426, "Transfer aborted. Data connection closed."); 2186 reply(226, "Abort successful"); 2187 } 2188 if (strcmp(cp, "STAT\r\n") == 0) { 2189 tmpline[0] = '\0'; 2190 if (file_size != -1) 2191 reply(213, "Status: %lld of %lld bytes transferred", 2192 (long long)byte_count, (long long)file_size); 2193 else 2194 reply(213, "Status: %lld bytes transferred", 2195 (long long)byte_count); 2196 } 2197} 2198 2199/* 2200 * Note: a response of 425 is not mentioned as a possible response to 2201 * the PASV command in RFC959. However, it has been blessed as 2202 * a legitimate response by Jon Postel in a telephone conversation 2203 * with Rick Adams on 25 Jan 89. 2204 */ 2205void 2206passive(void) 2207{ 2208 socklen_t len; 2209 int on = 1; 2210 u_char *p, *a; 2211 2212 if (pw == NULL) { 2213 reply(530, "Please login with USER and PASS"); 2214 return; 2215 } 2216 if (pdata >= 0) 2217 close(pdata); 2218 /* 2219 * XXX 2220 * At this point, it would be nice to have an algorithm that 2221 * inserted a growing delay in an attack scenario. Such a thing 2222 * would look like continual passive sockets being opened, but 2223 * nothing serious being done with them. They're not used to 2224 * move data; the entire attempt is just to use tcp FIN_WAIT 2225 * resources. 2226 */ 2227 pdata = socket(AF_INET, SOCK_STREAM, 0); 2228 if (pdata < 0) { 2229 perror_reply(425, "Can't open passive connection"); 2230 return; 2231 } 2232 2233 if (setsockopt(pdata, SOL_SOCKET, SO_KEEPALIVE, 2234 &on, sizeof(on)) < 0) 2235 goto pasv_error; 2236 2237 on = IP_PORTRANGE_HIGH; 2238 if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE, 2239 &on, sizeof(on)) < 0) 2240 goto pasv_error; 2241 2242 pasv_addr = ctrl_addr; 2243 pasv_addr.su_sin.sin_port = 0; 2244 if (bind(pdata, (struct sockaddr *)&pasv_addr, 2245 pasv_addr.su_len) < 0) 2246 goto pasv_error; 2247 2248 len = sizeof(pasv_addr); 2249 if (getsockname(pdata, (struct sockaddr *)&pasv_addr, &len) < 0) 2250 goto pasv_error; 2251 if (listen(pdata, 1) < 0) 2252 goto pasv_error; 2253 a = (u_char *)&pasv_addr.su_sin.sin_addr; 2254 p = (u_char *)&pasv_addr.su_sin.sin_port; 2255 2256 reply(227, "Entering Passive Mode (%u,%u,%u,%u,%u,%u)", a[0], 2257 a[1], a[2], a[3], p[0], p[1]); 2258 return; 2259 2260pasv_error: 2261 perror_reply(425, "Can't open passive connection"); 2262 (void) close(pdata); 2263 pdata = -1; 2264 return; 2265} 2266 2267int 2268epsvproto2af(int proto) 2269{ 2270 2271 switch (proto) { 2272 case 1: return AF_INET; 2273 case 2: return AF_INET6; 2274 default: return -1; 2275 } 2276} 2277 2278int 2279af2epsvproto(int af) 2280{ 2281 2282 switch (af) { 2283 case AF_INET: return 1; 2284 case AF_INET6: return 2; 2285 default: return -1; 2286 } 2287} 2288 2289/* 2290 * 228 Entering Long Passive Mode (af, hal, h1, h2, h3,..., pal, p1, p2...) 2291 * 229 Entering Extended Passive Mode (|||port|) 2292 */ 2293void 2294long_passive(char *cmd, int pf) 2295{ 2296 socklen_t len; 2297 int on = 1; 2298 u_char *p, *a; 2299 2300 if (!logged_in) { 2301 syslog(LOG_NOTICE, "long passive but not logged in"); 2302 reply(503, "Login with USER first."); 2303 return; 2304 } 2305 2306 if (pf != PF_UNSPEC && ctrl_addr.su_family != pf) { 2307 /* 2308 * XXX 2309 * only EPRT/EPSV ready clients will understand this 2310 */ 2311 if (strcmp(cmd, "EPSV") != 0) 2312 reply(501, "Network protocol mismatch"); /*XXX*/ 2313 else 2314 epsv_protounsupp("Network protocol mismatch"); 2315 2316 return; 2317 } 2318 2319 if (pdata >= 0) 2320 close(pdata); 2321 /* 2322 * XXX 2323 * At this point, it would be nice to have an algorithm that 2324 * inserted a growing delay in an attack scenario. Such a thing 2325 * would look like continual passive sockets being opened, but 2326 * nothing serious being done with them. They not used to move 2327 * data; the entire attempt is just to use tcp FIN_WAIT 2328 * resources. 2329 */ 2330 pdata = socket(ctrl_addr.su_family, SOCK_STREAM, 0); 2331 if (pdata < 0) { 2332 perror_reply(425, "Can't open passive connection"); 2333 return; 2334 } 2335 2336 if (setsockopt(pdata, SOL_SOCKET, SO_KEEPALIVE, 2337 &on, sizeof(on)) < 0) 2338 goto pasv_error; 2339 2340 switch (ctrl_addr.su_family) { 2341 case AF_INET: 2342 on = IP_PORTRANGE_HIGH; 2343 if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE, 2344 &on, sizeof(on)) < 0) 2345 goto pasv_error; 2346 break; 2347 case AF_INET6: 2348 on = IPV6_PORTRANGE_HIGH; 2349 if (setsockopt(pdata, IPPROTO_IPV6, IPV6_PORTRANGE, 2350 &on, sizeof(on)) < 0) 2351 goto pasv_error; 2352 break; 2353 } 2354 2355 pasv_addr = ctrl_addr; 2356 pasv_addr.su_port = 0; 2357 if (bind(pdata, (struct sockaddr *)&pasv_addr, pasv_addr.su_len) < 0) 2358 goto pasv_error; 2359 len = pasv_addr.su_len; 2360 if (getsockname(pdata, (struct sockaddr *)&pasv_addr, &len) < 0) 2361 goto pasv_error; 2362 if (listen(pdata, 1) < 0) 2363 goto pasv_error; 2364 p = (u_char *)&pasv_addr.su_port; 2365 2366 if (strcmp(cmd, "LPSV") == 0) { 2367 switch (pasv_addr.su_family) { 2368 case AF_INET: 2369 a = (u_char *)&pasv_addr.su_sin.sin_addr; 2370 reply(228, 2371 "Entering Long Passive Mode (%u,%u,%u,%u,%u,%u,%u,%u,%u)", 2372 4, 4, a[0], a[1], a[2], a[3], 2, p[0], p[1]); 2373 return; 2374 case AF_INET6: 2375 a = (u_char *)&pasv_addr.su_sin6.sin6_addr; 2376 reply(228, 2377 "Entering Long Passive Mode (%u,%u,%u,%u,%u,%u," 2378 "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u)", 2379 6, 16, a[0], a[1], a[2], a[3], a[4], 2380 a[5], a[6], a[7], a[8], a[9], a[10], 2381 a[11], a[12], a[13], a[14], a[15], 2382 2, p[0], p[1]); 2383 return; 2384 } 2385 } else if (strcmp(cmd, "EPSV") == 0) { 2386 switch (pasv_addr.su_family) { 2387 case AF_INET: 2388 case AF_INET6: 2389 reply(229, "Entering Extended Passive Mode (|||%u|)", 2390 ntohs(pasv_addr.su_port)); 2391 return; 2392 } 2393 } else { 2394 /* more proper error code? */ 2395 } 2396 2397 pasv_error: 2398 perror_reply(425, "Can't open passive connection"); 2399 (void) close(pdata); 2400 pdata = -1; 2401 return; 2402} 2403 2404/* 2405 * EPRT |proto|addr|port| 2406 */ 2407int 2408extended_port(const char *arg) 2409{ 2410 char *tmp = NULL; 2411 char *result[3]; 2412 char *p, *q; 2413 char delim; 2414 struct addrinfo hints; 2415 struct addrinfo *res = NULL; 2416 int i; 2417 unsigned long proto; 2418 2419 if (epsvall) { 2420 reply(501, "EPRT disallowed after EPSV ALL"); 2421 return -1; 2422 } 2423 2424 usedefault = 0; 2425 if (pdata >= 0) { 2426 (void) close(pdata); 2427 pdata = -1; 2428 } 2429 2430 tmp = strdup(arg); 2431 if (!tmp) { 2432 fatal("not enough core."); 2433 /*NOTREACHED*/ 2434 } 2435 p = tmp; 2436 delim = p[0]; 2437 p++; 2438 memset(result, 0, sizeof(result)); 2439 for (i = 0; i < 3; i++) { 2440 q = strchr(p, delim); 2441 if (!q || *q != delim) 2442 goto parsefail; 2443 *q++ = '\0'; 2444 result[i] = p; 2445 p = q; 2446 } 2447 2448 /* some more sanity check */ 2449 p = NULL; 2450 (void)strtoul(result[2], &p, 10); 2451 if (!*result[2] || *p) 2452 goto protounsupp; 2453 p = NULL; 2454 proto = strtoul(result[0], &p, 10); 2455 if (!*result[0] || *p) 2456 goto protounsupp; 2457 2458 memset(&hints, 0, sizeof(hints)); 2459 hints.ai_family = epsvproto2af((int)proto); 2460 if (hints.ai_family < 0) 2461 goto protounsupp; 2462 hints.ai_socktype = SOCK_STREAM; 2463 hints.ai_flags = AI_NUMERICHOST; /*no DNS*/ 2464 if (getaddrinfo(result[1], result[2], &hints, &res)) 2465 goto parsefail; 2466 if (res->ai_next) 2467 goto parsefail; 2468 if (sizeof(data_dest) < res->ai_addrlen) 2469 goto parsefail; 2470 memcpy(&data_dest, res->ai_addr, res->ai_addrlen); 2471 if (his_addr.su_family == AF_INET6 && 2472 data_dest.su_family == AF_INET6) { 2473 /* XXX more sanity checks! */ 2474 data_dest.su_sin6.sin6_scope_id = 2475 his_addr.su_sin6.sin6_scope_id; 2476 } 2477 if (pdata >= 0) { 2478 (void) close(pdata); 2479 pdata = -1; 2480 } 2481 reply(200, "EPRT command successful."); 2482 2483 free(tmp); 2484 if (res) 2485 freeaddrinfo(res); 2486 return 0; 2487 2488parsefail: 2489 reply(500, "Invalid argument, rejected."); 2490 usedefault = 1; 2491 free(tmp); 2492 if (res) 2493 freeaddrinfo(res); 2494 return -1; 2495 2496protounsupp: 2497 epsv_protounsupp("Protocol not supported"); 2498 usedefault = 1; 2499 free(tmp); 2500 if (res) 2501 freeaddrinfo(res); 2502 return -1; 2503} 2504 2505/* 2506 * 522 Protocol not supported (proto,...) 2507 * as we assume address family for control and data connections are the same, 2508 * we do not return the list of address families we support - instead, we 2509 * return the address family of the control connection. 2510 */ 2511void 2512epsv_protounsupp(const char *message) 2513{ 2514 int proto; 2515 2516 proto = af2epsvproto(ctrl_addr.su_family); 2517 if (proto < 0) 2518 reply(501, "%s", message); /*XXX*/ 2519 else 2520 reply(522, "%s, use (%d)", message, proto); 2521} 2522 2523/* 2524 * Generate unique name for file with basename "local". 2525 * The file named "local" is already known to exist. 2526 * Generates failure reply on error. 2527 */ 2528static int 2529guniquefd(char *local, char **nam) 2530{ 2531 static char new[PATH_MAX]; 2532 struct stat st; 2533 int count, len, fd; 2534 char *cp; 2535 2536 cp = strrchr(local, '/'); 2537 if (cp) 2538 *cp = '\0'; 2539 if (stat(cp ? local : ".", &st) < 0) { 2540 perror_reply(553, cp ? local : "."); 2541 return (-1); 2542 } 2543 if (cp) 2544 *cp = '/'; 2545 len = strlcpy(new, local, sizeof(new)); 2546 if (len+2+1 >= sizeof(new)-1) 2547 return (-1); 2548 cp = new + len; 2549 *cp++ = '.'; 2550 for (count = 1; count < 100; count++) { 2551 (void)snprintf(cp, sizeof(new) - (cp - new), "%d", count); 2552 fd = open(new, O_RDWR|O_CREAT|O_EXCL, 0666); 2553 if (fd == -1) 2554 continue; 2555 if (nam) 2556 *nam = new; 2557 return (fd); 2558 } 2559 reply(452, "Unique file name cannot be created."); 2560 return (-1); 2561} 2562 2563/* 2564 * Format and send reply containing system error number. 2565 */ 2566void 2567perror_reply(int code, char *string) 2568{ 2569 2570 reply(code, "%s: %s.", string, strerror(errno)); 2571} 2572 2573static char *onefile[] = { 2574 "", 2575 0 2576}; 2577 2578void 2579send_file_list(char *whichf) 2580{ 2581 struct stat st; 2582 DIR *dirp = NULL; 2583 struct dirent *dir; 2584 FILE *dout = NULL; 2585 char **dirlist; 2586 char *dirname; 2587 int simple = 0; 2588 volatile int freeglob = 0; 2589 glob_t gl; 2590 size_t prefixlen; 2591 2592 if (strpbrk(whichf, "~{[*?") != NULL) { 2593 memset(&gl, 0, sizeof(gl)); 2594 freeglob = 1; 2595 if (glob(whichf, 2596 GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE|GLOB_LIMIT, 2597 0, &gl)) { 2598 reply(550, "not found"); 2599 goto out; 2600 } else if (gl.gl_pathc == 0) { 2601 errno = ENOENT; 2602 perror_reply(550, whichf); 2603 goto out; 2604 } 2605 dirlist = gl.gl_pathv; 2606 } else { 2607 onefile[0] = whichf; 2608 dirlist = onefile; 2609 simple = 1; 2610 } 2611 2612 while ((dirname = *dirlist++)) { 2613 if (stat(dirname, &st) < 0) { 2614 /* 2615 * If user typed "ls -l", etc, and the client 2616 * used NLST, do what the user meant. 2617 */ 2618 if (dirname[0] == '-' && *dirlist == NULL && 2619 transflag == 0) { 2620 retrieve("/bin/ls %s", dirname); 2621 goto out; 2622 } 2623 perror_reply(550, whichf); 2624 if (dout != NULL) { 2625 (void) fclose(dout); 2626 transflag = 0; 2627 data = -1; 2628 pdata = -1; 2629 } 2630 goto out; 2631 } 2632 2633 if (S_ISREG(st.st_mode)) { 2634 if (dout == NULL) { 2635 dout = dataconn("file list", -1, "w"); 2636 if (dout == NULL) 2637 goto out; 2638 transflag++; 2639 } 2640 fprintf(dout, "%s%s\n", dirname, 2641 type == TYPE_A ? "\r" : ""); 2642 byte_count += strlen(dirname) + 1; 2643 continue; 2644 } else if (!S_ISDIR(st.st_mode)) 2645 continue; 2646 2647 if ((dirp = opendir(dirname)) == NULL) 2648 continue; 2649 2650 if (dirname[0] == '.' && dirname[1] == '\0') 2651 prefixlen = 0; 2652 else 2653 prefixlen = strlen(dirname) + 1; 2654 while ((dir = readdir(dirp)) != NULL) { 2655 if (recvurg) { 2656 myoob(); 2657 recvurg = 0; 2658 transflag = 0; 2659 goto out; 2660 } 2661 2662 if (dir->d_name[0] == '.' && dir->d_namlen == 1) 2663 continue; 2664 if (dir->d_name[0] == '.' && dir->d_name[1] == '.' && 2665 dir->d_namlen == 2) 2666 continue; 2667 2668 /* 2669 * We have to do a stat to insure it's 2670 * not a directory or special file. 2671 */ 2672 if (simple || 2673 (fstatat(dirfd(dirp), dir->d_name, &st, 0) == 0 && 2674 S_ISREG(st.st_mode))) { 2675 if (dout == NULL) { 2676 dout = dataconn("file list", -1, "w"); 2677 if (dout == NULL) 2678 goto out; 2679 transflag++; 2680 } 2681 2682 if (prefixlen) { 2683 fprintf(dout, "%s/", dirname); 2684 byte_count += prefixlen; 2685 } 2686 fprintf(dout, "%s%s\n", dir->d_name, 2687 type == TYPE_A ? "\r" : ""); 2688 byte_count += dir->d_namlen + 1; 2689 } 2690 } 2691 (void) closedir(dirp); 2692 } 2693 2694 if (dout == NULL) 2695 reply(550, "No files found."); 2696 else if (ferror(dout) != 0) 2697 perror_reply(550, "Data connection"); 2698 else 2699 reply(226, "Transfer complete."); 2700 2701 transflag = 0; 2702 if (dout != NULL) 2703 (void) fclose(dout); 2704 else { 2705 if (pdata >= 0) 2706 close(pdata); 2707 } 2708 data = -1; 2709 pdata = -1; 2710out: 2711 if (freeglob) { 2712 freeglob = 0; 2713 globfree(&gl); 2714 } 2715} 2716 2717/*ARGSUSED*/ 2718static void 2719reapchild(int signo) 2720{ 2721 int save_errno = errno; 2722 int rval; 2723 2724 do { 2725 rval = waitpid(-1, NULL, WNOHANG); 2726 } while (rval > 0 || (rval == -1 && errno == EINTR)); 2727 errno = save_errno; 2728} 2729 2730void 2731logxfer(char *name, off_t size, time_t start) 2732{ 2733 char buf[400 + (HOST_NAME_MAX+1)*4 + PATH_MAX*4]; 2734 char dir[PATH_MAX], path[PATH_MAX], rpath[PATH_MAX]; 2735 char vremotehost[(HOST_NAME_MAX+1)*4], vpath[PATH_MAX*4]; 2736 char *vpw; 2737 time_t now; 2738 int len; 2739 2740 if ((statfd >= 0) && (getcwd(dir, sizeof(dir)) != NULL)) { 2741 time(&now); 2742 2743 vpw = malloc(strlen(guest ? guestpw : pw->pw_name) * 4 + 1); 2744 if (vpw == NULL) 2745 return; 2746 2747 snprintf(path, sizeof(path), "%s/%s", dir, name); 2748 if (realpath(path, rpath) == NULL) 2749 strlcpy(rpath, path, sizeof(rpath)); 2750 strvis(vpath, rpath, VIS_SAFE|VIS_NOSLASH); 2751 2752 strvis(vremotehost, remotehost, VIS_SAFE|VIS_NOSLASH); 2753 strvis(vpw, guest? guestpw : pw->pw_name, VIS_SAFE|VIS_NOSLASH); 2754 2755 len = snprintf(buf, sizeof(buf), 2756 "%.24s %lld %s %lld %s %c %s %c %c %s ftp %d %s %s\n", 2757 ctime(&now), (long long)(now - start + (now == start)), 2758 vremotehost, (long long)size, vpath, 2759 ((type == TYPE_A) ? 'a' : 'b'), "*" /* none yet */, 2760 'o', ((guest) ? 'a' : 'r'), 2761 vpw, 0 /* none yet */, 2762 ((guest) ? "*" : pw->pw_name), dhostname); 2763 free(vpw); 2764 2765 if (len >= sizeof(buf) || len == -1) { 2766 if ((len = strlen(buf)) == 0) 2767 return; /* should not happen */ 2768 buf[len - 1] = '\n'; 2769 } 2770 write(statfd, buf, len); 2771 } 2772} 2773 2774void 2775set_slave_signals(void) 2776{ 2777 struct sigaction sa; 2778 2779 sigemptyset(&sa.sa_mask); 2780 sa.sa_flags = SA_RESTART; 2781 2782 sa.sa_handler = SIG_DFL; 2783 (void) sigaction(SIGCHLD, &sa, NULL); 2784 2785 sa.sa_handler = sigurg; 2786 sa.sa_flags = 0; /* don't restart syscalls for SIGURG */ 2787 (void) sigaction(SIGURG, &sa, NULL); 2788 2789 sigfillset(&sa.sa_mask); /* block all signals in handler */ 2790 sa.sa_flags = SA_RESTART; 2791 sa.sa_handler = sigquit; 2792 (void) sigaction(SIGHUP, &sa, NULL); 2793 (void) sigaction(SIGINT, &sa, NULL); 2794 (void) sigaction(SIGQUIT, &sa, NULL); 2795 (void) sigaction(SIGTERM, &sa, NULL); 2796 2797 sa.sa_handler = lostconn; 2798 (void) sigaction(SIGPIPE, &sa, NULL); 2799 2800 sa.sa_handler = toolong; 2801 (void) sigaction(SIGALRM, &sa, NULL); 2802 2803 if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1) 2804 syslog(LOG_ERR, "fcntl F_SETOWN: %m"); 2805} 2806 2807/* 2808 * Allocate space and return a copy of the specified dir. 2809 * If 'dir' begins with a tilde (~), expand it. 2810 */ 2811char * 2812copy_dir(char *dir, struct passwd *pw) 2813{ 2814 char *cp; 2815 char *newdir; 2816 char *user = NULL; 2817 2818 /* Nothing to expand */ 2819 if (dir[0] != '~') 2820 return (strdup(dir)); 2821 2822 /* "dir" is of form ~user/some/dir, lookup user. */ 2823 if (dir[1] != '/' && dir[1] != '\0') { 2824 if ((cp = strchr(dir + 1, '/')) == NULL) 2825 cp = dir + strlen(dir); 2826 if ((user = malloc((size_t)(cp - dir))) == NULL) 2827 return (NULL); 2828 strlcpy(user, dir + 1, (size_t)(cp - dir)); 2829 2830 /* Only do lookup if it is a different user. */ 2831 if (strcmp(user, pw->pw_name) != 0) { 2832 if ((pw = getpwnam(user)) == NULL) { 2833 /* No such user, interpret literally */ 2834 free(user); 2835 return(strdup(dir)); 2836 } 2837 } 2838 free(user); 2839 } 2840 2841 /* 2842 * If there is no directory separator (/) then it is just pw_dir. 2843 * Otherwise, replace ~foo with pw_dir. 2844 */ 2845 if ((cp = strchr(dir + 1, '/')) == NULL) { 2846 newdir = strdup(pw->pw_dir); 2847 } else { 2848 if (asprintf(&newdir, "%s%s", pw->pw_dir, cp) == -1) 2849 return (NULL); 2850 } 2851 2852 return(newdir); 2853} 2854