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