ftpd.c (51433) | ftpd.c (56668) |
---|---|
1/* 2 * Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 30 unchanged lines hidden (view full) --- 39#endif /* not lint */ 40#endif 41 42#ifndef lint 43#if 0 44static char sccsid[] = "@(#)ftpd.c 8.4 (Berkeley) 4/16/94"; 45#endif 46static const char rcsid[] = | 1/* 2 * Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 30 unchanged lines hidden (view full) --- 39#endif /* not lint */ 40#endif 41 42#ifndef lint 43#if 0 44static char sccsid[] = "@(#)ftpd.c 8.4 (Berkeley) 4/16/94"; 45#endif 46static const char rcsid[] = |
47 "$FreeBSD: head/libexec/ftpd/ftpd.c 51433 1999-09-19 22:05:32Z markm $"; | 47 "$FreeBSD: head/libexec/ftpd/ftpd.c 56668 2000-01-27 09:28:38Z shin $"; |
48#endif /* not lint */ 49 50/* 51 * FTP server. 52 */ 53#include <sys/param.h> 54#include <sys/stat.h> 55#include <sys/ioctl.h> --- 49 unchanged lines hidden (view full) --- 105#include <stdarg.h> 106#else 107#include <varargs.h> 108#endif 109 110static char version[] = "Version 6.00LS"; 111#undef main 112 | 48#endif /* not lint */ 49 50/* 51 * FTP server. 52 */ 53#include <sys/param.h> 54#include <sys/stat.h> 55#include <sys/ioctl.h> --- 49 unchanged lines hidden (view full) --- 105#include <stdarg.h> 106#else 107#include <varargs.h> 108#endif 109 110static char version[] = "Version 6.00LS"; 111#undef main 112 |
113/* wrapper for KAME-special getnameinfo() */ 114#ifndef NI_WITHSCOPEID 115#define NI_WITHSCOPEID 0 116#endif 117 |
|
113extern off_t restart_point; 114extern char cbuf[]; 115 | 118extern off_t restart_point; 119extern char cbuf[]; 120 |
116struct sockaddr_in server_addr; 117struct sockaddr_in ctrl_addr; 118struct sockaddr_in data_source; 119struct sockaddr_in data_dest; 120struct sockaddr_in his_addr; 121struct sockaddr_in pasv_addr; | 121union sockunion server_addr; 122union sockunion ctrl_addr; 123union sockunion data_source; 124union sockunion data_dest; 125union sockunion his_addr; 126union sockunion pasv_addr; |
122 123int daemon_mode; 124int data; 125jmp_buf errcatch, urgcatch; 126int logged_in; 127struct passwd *pw; 128int debug; 129int timeout = 900; /* timeout after 15 minutes of inactivity */ --- 20 unchanged lines hidden (view full) --- 150#define CMASK 027 151#endif 152int defumask = CMASK; /* default umask value */ 153char tmpline[7]; 154char *hostname; 155#ifdef VIRTUAL_HOSTING 156char *ftpuser; 157 | 127 128int daemon_mode; 129int data; 130jmp_buf errcatch, urgcatch; 131int logged_in; 132struct passwd *pw; 133int debug; 134int timeout = 900; /* timeout after 15 minutes of inactivity */ --- 20 unchanged lines hidden (view full) --- 155#define CMASK 027 156#endif 157int defumask = CMASK; /* default umask value */ 158char tmpline[7]; 159char *hostname; 160#ifdef VIRTUAL_HOSTING 161char *ftpuser; 162 |
163int epsvall = 0; 164 |
|
158static struct ftphost { 159 struct ftphost *next; | 165static struct ftphost { 166 struct ftphost *next; |
160 struct in_addr hostaddr; | 167 union sockunion hostaddr; |
161 char *hostname; 162 char *anonuser; 163 char *statfile; 164 char *welcome; 165 char *loginmsg; 166} *thishost, *firsthost; 167 168#endif 169char remotehost[MAXHOSTNAMELEN]; 170char *ident = NULL; 171 172static char ttyline[20]; 173char *tty = ttyline; /* for klogin */ 174 175#if !defined(NOPAM) 176static int auth_pam __P((struct passwd**, const char*)); 177#endif 178 | 168 char *hostname; 169 char *anonuser; 170 char *statfile; 171 char *welcome; 172 char *loginmsg; 173} *thishost, *firsthost; 174 175#endif 176char remotehost[MAXHOSTNAMELEN]; 177char *ident = NULL; 178 179static char ttyline[20]; 180char *tty = ttyline; /* for klogin */ 181 182#if !defined(NOPAM) 183static int auth_pam __P((struct passwd**, const char*)); 184#endif 185 |
179struct in_addr bind_address; | |
180char *pid_file = NULL; 181 182/* 183 * Timeout intervals for retrying connections 184 * to hosts that don't accept PORT cmds. This 185 * is a kludge, but given the problems with TCP... 186 */ 187#define SWAITMAX 90 /* wait at most 90 seconds */ --- 7 unchanged lines hidden (view full) --- 195char **Argv = NULL; /* pointer to argument vector */ 196char *LastArgv = NULL; /* end of argv */ 197#endif /* OLD_SETPROCTITLE */ 198char proctitle[LINE_MAX]; /* initial part of title */ 199#endif /* SETPROCTITLE */ 200 201#ifdef SKEY 202int pwok = 0; | 186char *pid_file = NULL; 187 188/* 189 * Timeout intervals for retrying connections 190 * to hosts that don't accept PORT cmds. This 191 * is a kludge, but given the problems with TCP... 192 */ 193#define SWAITMAX 90 /* wait at most 90 seconds */ --- 7 unchanged lines hidden (view full) --- 201char **Argv = NULL; /* pointer to argument vector */ 202char *LastArgv = NULL; /* end of argv */ 203#endif /* OLD_SETPROCTITLE */ 204char proctitle[LINE_MAX]; /* initial part of title */ 205#endif /* SETPROCTITLE */ 206 207#ifdef SKEY 208int pwok = 0; |
203char addr_string[20]; /* XXX */ | 209char addr_string[INET6_ADDRSTRLEN]; /* XXX */ |
204#endif 205 206#define LOGCMD(cmd, file) \ 207 if (logging > 1) \ 208 syslog(LOG_INFO,"%s %s%s", cmd, \ 209 *(file) == '/' ? "" : curdir(), file); 210#define LOGCMD2(cmd, file1, file2) \ 211 if (logging > 1) \ --- 7 unchanged lines hidden (view full) --- 219 *(file) == '/' ? "" : curdir(), file); \ 220 else \ 221 syslog(LOG_INFO, "%s %s%s = %qd bytes", \ 222 cmd, (*(file) == '/') ? "" : curdir(), file, cnt); \ 223 } 224 225#ifdef VIRTUAL_HOSTING 226static void inithosts __P((void)); | 210#endif 211 212#define LOGCMD(cmd, file) \ 213 if (logging > 1) \ 214 syslog(LOG_INFO,"%s %s%s", cmd, \ 215 *(file) == '/' ? "" : curdir(), file); 216#define LOGCMD2(cmd, file1, file2) \ 217 if (logging > 1) \ --- 7 unchanged lines hidden (view full) --- 225 *(file) == '/' ? "" : curdir(), file); \ 226 else \ 227 syslog(LOG_INFO, "%s %s%s = %qd bytes", \ 228 cmd, (*(file) == '/') ? "" : curdir(), file, cnt); \ 229 } 230 231#ifdef VIRTUAL_HOSTING 232static void inithosts __P((void)); |
227static void selecthost __P((struct in_addr *)); | 233static void selecthost __P((union sockunion *)); |
228#endif 229static void ack __P((char *)); 230static void myoob __P((int)); 231static int checkuser __P((char *, char *, int)); 232static FILE *dataconn __P((char *, off_t, char *)); | 234#endif 235static void ack __P((char *)); 236static void myoob __P((int)); 237static int checkuser __P((char *, char *, int)); 238static FILE *dataconn __P((char *, off_t, char *)); |
233static void dolog __P((struct sockaddr_in *)); | 239static void dolog __P((struct sockaddr *)); |
234static char *curdir __P((void)); 235static void end_login __P((void)); 236static FILE *getdatasock __P((char *)); 237static char *gunique __P((char *)); 238static void lostconn __P((int)); 239static int receive_data __P((FILE *, FILE *)); 240static void send_data __P((FILE *, FILE *, off_t, off_t, int)); 241static struct passwd * --- 19 unchanged lines hidden (view full) --- 261main(argc, argv, envp) 262 int argc; 263 char *argv[]; 264 char **envp; 265{ 266 int addrlen, ch, on = 1, tos; 267 char *cp, line[LINE_MAX]; 268 FILE *fd; | 240static char *curdir __P((void)); 241static void end_login __P((void)); 242static FILE *getdatasock __P((char *)); 243static char *gunique __P((char *)); 244static void lostconn __P((int)); 245static int receive_data __P((FILE *, FILE *)); 246static void send_data __P((FILE *, FILE *, off_t, off_t, int)); 247static struct passwd * --- 19 unchanged lines hidden (view full) --- 267main(argc, argv, envp) 268 int argc; 269 char *argv[]; 270 char **envp; 271{ 272 int addrlen, ch, on = 1, tos; 273 char *cp, line[LINE_MAX]; 274 FILE *fd; |
275 int error; 276 char *bindname = NULL; 277 int family = AF_UNSPEC; 278 int enable_v4 = 0; |
|
269 270 tzset(); /* in case no timezone database in ~ftp */ 271 272#ifdef OLD_SETPROCTITLE 273 /* 274 * Save start and extent of argv for setproctitle. 275 */ 276 Argv = argv; 277 while (*envp) 278 envp++; 279 LastArgv = envp[-1] + strlen(envp[-1]); 280#endif /* OLD_SETPROCTITLE */ 281 282 | 279 280 tzset(); /* in case no timezone database in ~ftp */ 281 282#ifdef OLD_SETPROCTITLE 283 /* 284 * Save start and extent of argv for setproctitle. 285 */ 286 Argv = argv; 287 while (*envp) 288 envp++; 289 LastArgv = envp[-1] + strlen(envp[-1]); 290#endif /* OLD_SETPROCTITLE */ 291 292 |
283 bind_address.s_addr = htonl(INADDR_ANY); 284 while ((ch = getopt(argc, argv, "AdlDSURt:T:u:va:p:")) != -1) { | 293 while ((ch = getopt(argc, argv, "AdlDSURt:T:u:va:p:46")) != -1) { |
285 switch (ch) { 286 case 'D': 287 daemon_mode++; 288 break; 289 290 case 'd': 291 debug++; 292 break; --- 22 unchanged lines hidden (view full) --- 315 maxtimeout = timeout; 316 break; 317 318 case 'U': 319 restricted_data_ports = 0; 320 break; 321 322 case 'a': | 294 switch (ch) { 295 case 'D': 296 daemon_mode++; 297 break; 298 299 case 'd': 300 debug++; 301 break; --- 22 unchanged lines hidden (view full) --- 324 maxtimeout = timeout; 325 break; 326 327 case 'U': 328 restricted_data_ports = 0; 329 break; 330 331 case 'a': |
323 if (!inet_aton(optarg, &bind_address)) 324 errx(1, "invalid address for -a"); | 332 bindname = optarg; |
325 break; 326 327 case 'p': 328 pid_file = optarg; 329 break; 330 331 case 'u': 332 { --- 9 unchanged lines hidden (view full) --- 342 case 'A': 343 anon_only = 1; 344 break; 345 346 case 'v': 347 debug = 1; 348 break; 349 | 333 break; 334 335 case 'p': 336 pid_file = optarg; 337 break; 338 339 case 'u': 340 { --- 9 unchanged lines hidden (view full) --- 350 case 'A': 351 anon_only = 1; 352 break; 353 354 case 'v': 355 debug = 1; 356 break; 357 |
358 case '4': 359 enable_v4 = 1; 360 if (family == AF_UNSPEC) 361 family = AF_INET; 362 break; 363 364 case '6': 365 family = AF_INET6; 366 break; 367 |
|
350 default: 351 warnx("unknown flag -%c ignored", optopt); 352 break; 353 } 354 } 355 356#ifdef VIRTUAL_HOSTING 357 inithosts(); 358#endif 359 (void) freopen(_PATH_DEVNULL, "w", stderr); 360 361 /* 362 * LOG_NDELAY sets up the logging connection immediately, 363 * necessary for anonymous ftp's that chroot and can't do it later. 364 */ 365 openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP); 366 367 if (daemon_mode) { 368 int ctl_sock, fd; | 368 default: 369 warnx("unknown flag -%c ignored", optopt); 370 break; 371 } 372 } 373 374#ifdef VIRTUAL_HOSTING 375 inithosts(); 376#endif 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 (daemon_mode) { 386 int ctl_sock, fd; |
369 struct servent *sv; | 387 struct addrinfo hints, *res; |
370 371 /* 372 * Detach from parent. 373 */ 374 if (daemon(1, 1) < 0) { 375 syslog(LOG_ERR, "failed to become a daemon"); 376 exit(1); 377 } 378 (void) signal(SIGCHLD, reapchild); | 388 389 /* 390 * Detach from parent. 391 */ 392 if (daemon(1, 1) < 0) { 393 syslog(LOG_ERR, "failed to become a daemon"); 394 exit(1); 395 } 396 (void) signal(SIGCHLD, reapchild); |
379 /* 380 * Get port number for ftp/tcp. 381 */ 382 sv = getservbyname("ftp", "tcp"); 383 if (sv == NULL) { 384 syslog(LOG_ERR, "getservbyname for ftp failed"); | 397 /* init bind_sa */ 398 memset(&hints, 0, sizeof(hints)); 399 400 hints.ai_family = family == AF_UNSPEC ? AF_INET : family; 401 hints.ai_socktype = SOCK_STREAM; 402 hints.ai_protocol = 0; 403 hints.ai_flags = AI_PASSIVE; 404 error = getaddrinfo(bindname, "ftp", &hints, &res); 405 if (error) { 406 if (family == AF_UNSPEC) { 407 hints.ai_family = AF_UNSPEC; 408 error = getaddrinfo(bindname, "ftp", &hints, 409 &res); 410 } 411 if (error == 0 && res->ai_addr != NULL) 412 family = res->ai_addr->sa_family; 413 } 414 if (error) { 415 syslog(LOG_ERR, gai_strerror(error)); 416 if (error == EAI_SYSTEM) 417 syslog(LOG_ERR, strerror(errno)); |
385 exit(1); 386 } | 418 exit(1); 419 } |
420 if (res->ai_addr == NULL) { 421 syslog(LOG_ERR, "-a %s: getaddrinfo failed", hostname); 422 exit(1); 423 } |
|
387 /* 388 * Open a socket, bind it to the FTP port, and start 389 * listening. 390 */ | 424 /* 425 * Open a socket, bind it to the FTP port, and start 426 * listening. 427 */ |
391 ctl_sock = socket(AF_INET, SOCK_STREAM, 0); | 428 ctl_sock = socket(family, SOCK_STREAM, 0); |
392 if (ctl_sock < 0) { 393 syslog(LOG_ERR, "control socket: %m"); 394 exit(1); 395 } 396 if (setsockopt(ctl_sock, SOL_SOCKET, SO_REUSEADDR, 397 (char *)&on, sizeof(on)) < 0) | 429 if (ctl_sock < 0) { 430 syslog(LOG_ERR, "control socket: %m"); 431 exit(1); 432 } 433 if (setsockopt(ctl_sock, SOL_SOCKET, SO_REUSEADDR, 434 (char *)&on, sizeof(on)) < 0) |
398 syslog(LOG_ERR, "control setsockopt: %m");; 399 server_addr.sin_family = AF_INET; 400 server_addr.sin_addr = bind_address; 401 server_addr.sin_port = sv->s_port; 402 if (bind(ctl_sock, (struct sockaddr *)&server_addr, sizeof(server_addr))) { | 435 syslog(LOG_ERR, "control setsockopt: %m"); 436#ifdef IPV6_BINDV6ONLY 437 if (family == AF_INET6 && enable_v4 == 0) { 438 if (setsockopt(ctl_sock, IPPROTO_IPV6, IPV6_BINDV6ONLY, 439 (char *)&on, sizeof (on)) < 0) 440 syslog(LOG_ERR, 441 "control setsockopt(IPV6_BINDV6ONLY): %m"); 442 } 443#endif /* IPV6_BINDV6ONLY */ 444 memcpy(&server_addr, res->ai_addr, res->ai_addr->sa_len); 445 if (bind(ctl_sock, (struct sockaddr *)&server_addr, 446 server_addr.su_len) < 0) { |
403 syslog(LOG_ERR, "control bind: %m"); 404 exit(1); 405 } 406 if (listen(ctl_sock, 32) < 0) { 407 syslog(LOG_ERR, "control listen: %m"); 408 exit(1); 409 } 410 /* --- 18 unchanged lines hidden (view full) --- 429 err(1, "%s: write", pid_file); 430 /* Leave the pid file open and locked */ 431 } 432 /* 433 * Loop forever accepting connection requests and forking off 434 * children to handle them. 435 */ 436 while (1) { | 447 syslog(LOG_ERR, "control bind: %m"); 448 exit(1); 449 } 450 if (listen(ctl_sock, 32) < 0) { 451 syslog(LOG_ERR, "control listen: %m"); 452 exit(1); 453 } 454 /* --- 18 unchanged lines hidden (view full) --- 473 err(1, "%s: write", pid_file); 474 /* Leave the pid file open and locked */ 475 } 476 /* 477 * Loop forever accepting connection requests and forking off 478 * children to handle them. 479 */ 480 while (1) { |
437 addrlen = sizeof(his_addr); | 481 addrlen = server_addr.su_len; |
438 fd = accept(ctl_sock, (struct sockaddr *)&his_addr, &addrlen); 439 if (fork() == 0) { 440 /* child */ 441 (void) dup2(fd, 0); 442 (void) dup2(fd, 1); 443 close(ctl_sock); 444 break; 445 } --- 8 unchanged lines hidden (view full) --- 454 } 455 456 (void) signal(SIGCHLD, SIG_IGN); 457 (void) signal(SIGPIPE, lostconn); 458 if (signal(SIGURG, myoob) == SIG_ERR) 459 syslog(LOG_ERR, "signal: %m"); 460 461#ifdef SKEY | 482 fd = accept(ctl_sock, (struct sockaddr *)&his_addr, &addrlen); 483 if (fork() == 0) { 484 /* child */ 485 (void) dup2(fd, 0); 486 (void) dup2(fd, 1); 487 close(ctl_sock); 488 break; 489 } --- 8 unchanged lines hidden (view full) --- 498 } 499 500 (void) signal(SIGCHLD, SIG_IGN); 501 (void) signal(SIGPIPE, lostconn); 502 if (signal(SIGURG, myoob) == SIG_ERR) 503 syslog(LOG_ERR, "signal: %m"); 504 505#ifdef SKEY |
462 strncpy(addr_string, inet_ntoa(his_addr.sin_addr), sizeof(addr_string)); | 506 getnameinfo((struct sockaddr *)&his_addr, his_addr.su_len, 507 addr_string, sizeof(addr_string) - 1, NULL, 0, 508 NI_NUMERICHOST|NI_WITHSCOPEID); |
463#endif 464 addrlen = sizeof(ctrl_addr); 465 if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) { 466 syslog(LOG_ERR, "getsockname (%s): %m",argv[0]); 467 exit(1); 468 } 469#ifdef VIRTUAL_HOSTING 470 /* select our identity from virtual host table */ | 509#endif 510 addrlen = sizeof(ctrl_addr); 511 if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) { 512 syslog(LOG_ERR, "getsockname (%s): %m",argv[0]); 513 exit(1); 514 } 515#ifdef VIRTUAL_HOSTING 516 /* select our identity from virtual host table */ |
471 selecthost(&ctrl_addr.sin_addr); | 517 selecthost(&ctrl_addr); |
472#endif 473#ifdef IP_TOS | 518#endif 519#ifdef IP_TOS |
520 if (ctrl_addr.su_family == AF_INET) 521 { |
|
474 tos = IPTOS_LOWDELAY; 475 if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) 476 syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); | 522 tos = IPTOS_LOWDELAY; 523 if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) 524 syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); |
525 } |
|
477#endif 478 /* 479 * Disable Nagle on the control channel so that we don't have to wait 480 * for peer's ACK before issuing our next reply. 481 */ 482 if (setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) 483 syslog(LOG_WARNING, "control setsockopt TCP_NODELAY: %m"); 484 | 526#endif 527 /* 528 * Disable Nagle on the control channel so that we don't have to wait 529 * for peer's ACK before issuing our next reply. 530 */ 531 if (setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) 532 syslog(LOG_WARNING, "control setsockopt TCP_NODELAY: %m"); 533 |
485 data_source.sin_port = htons(ntohs(ctrl_addr.sin_port) - 1); | 534 data_source.su_port = htons(ntohs(ctrl_addr.su_port) - 1); |
486 487 /* set this here so klogin can use it... */ 488 (void)snprintf(ttyline, sizeof(ttyline), "ftp%d", getpid()); 489 490 /* Try to handle urgent data inline */ 491#ifdef SO_OOBINLINE 492 if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)) < 0) 493 syslog(LOG_ERR, "setsockopt: %m"); 494#endif 495 496#ifdef F_SETOWN 497 if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1) 498 syslog(LOG_ERR, "fcntl F_SETOWN: %m"); 499#endif | 535 536 /* set this here so klogin can use it... */ 537 (void)snprintf(ttyline, sizeof(ttyline), "ftp%d", getpid()); 538 539 /* Try to handle urgent data inline */ 540#ifdef SO_OOBINLINE 541 if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)) < 0) 542 syslog(LOG_ERR, "setsockopt: %m"); 543#endif 544 545#ifdef F_SETOWN 546 if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1) 547 syslog(LOG_ERR, "fcntl F_SETOWN: %m"); 548#endif |
500 dolog(&his_addr); | 549 dolog((struct sockaddr *)&his_addr); |
501 /* 502 * Set up default state 503 */ 504 data = -1; 505 type = TYPE_A; 506 form = FORM_N; 507 stru = STRU_F; 508 mode = MODE_S; --- 53 unchanged lines hidden (view full) --- 562 * read in virtual host tables (if they exist) 563 */ 564 565static void 566inithosts() 567{ 568 FILE *fp; 569 char *cp; | 550 /* 551 * Set up default state 552 */ 553 data = -1; 554 type = TYPE_A; 555 form = FORM_N; 556 stru = STRU_F; 557 mode = MODE_S; --- 53 unchanged lines hidden (view full) --- 611 * read in virtual host tables (if they exist) 612 */ 613 614static void 615inithosts() 616{ 617 FILE *fp; 618 char *cp; |
570 struct hostent *hp; | |
571 struct ftphost *hrp, *lhrp; 572 char line[1024]; | 619 struct ftphost *hrp, *lhrp; 620 char line[1024]; |
621 struct addrinfo hints, *res, *ai; |
|
573 574 /* 575 * Fill in the default host information 576 */ 577 if (gethostname(line, sizeof(line)) < 0) 578 line[0] = '\0'; 579 if ((hrp = malloc(sizeof(struct ftphost))) == NULL || 580 (hrp->hostname = strdup(line)) == NULL) 581 fatal("Ran out of memory."); | 622 623 /* 624 * Fill in the default host information 625 */ 626 if (gethostname(line, sizeof(line)) < 0) 627 line[0] = '\0'; 628 if ((hrp = malloc(sizeof(struct ftphost))) == NULL || 629 (hrp->hostname = strdup(line)) == NULL) 630 fatal("Ran out of memory."); |
582 memset(&hrp->hostaddr, 0, sizeof hrp->hostaddr); 583 if ((hp = gethostbyname(hrp->hostname)) != NULL) 584 (void) memcpy(&hrp->hostaddr, 585 hp->h_addr_list[0], 586 sizeof(hrp->hostaddr)); | 631 memset(&hrp->hostaddr, 0, sizeof(hrp->hostaddr)); 632 633 memset(&hints, 0, sizeof(hints)); 634 hints.ai_flags = AI_CANONNAME; 635 hints.ai_family = AF_UNSPEC; 636 getaddrinfo(hrp->hostname, NULL, &hints, &res); 637 if (res) 638 memcpy(&hrp->hostaddr, res->ai_addr, res->ai_addrlen); |
587 hrp->statfile = _PATH_FTPDSTATFILE; 588 hrp->welcome = _PATH_FTPWELCOME; 589 hrp->loginmsg = _PATH_FTPLOGINMESG; 590 hrp->anonuser = "ftp"; 591 hrp->next = NULL; 592 thishost = firsthost = lhrp = hrp; | 639 hrp->statfile = _PATH_FTPDSTATFILE; 640 hrp->welcome = _PATH_FTPWELCOME; 641 hrp->loginmsg = _PATH_FTPLOGINMESG; 642 hrp->anonuser = "ftp"; 643 hrp->next = NULL; 644 thishost = firsthost = lhrp = hrp; |
645 freeaddrinfo(res); |
|
593 if ((fp = fopen(_PATH_FTPHOSTS, "r")) != NULL) { | 646 if ((fp = fopen(_PATH_FTPHOSTS, "r")) != NULL) { |
647 int addrsize, error; 648 void *addr; 649 struct hostent *hp; 650 |
|
594 while (fgets(line, sizeof(line), fp) != NULL) { | 651 while (fgets(line, sizeof(line), fp) != NULL) { |
595 int i; | 652 int i, hp_error; |
596 597 if ((cp = strchr(line, '\n')) == NULL) { 598 /* ignore long lines */ 599 while (fgets(line, sizeof(line), fp) != NULL && 600 strchr(line, '\n') == NULL) 601 ; 602 continue; 603 } 604 *cp = '\0'; 605 cp = strtok(line, " \t"); 606 /* skip comments and empty lines */ 607 if (cp == NULL || line[0] == '#') 608 continue; | 653 654 if ((cp = strchr(line, '\n')) == NULL) { 655 /* ignore long lines */ 656 while (fgets(line, sizeof(line), fp) != NULL && 657 strchr(line, '\n') == NULL) 658 ; 659 continue; 660 } 661 *cp = '\0'; 662 cp = strtok(line, " \t"); 663 /* skip comments and empty lines */ 664 if (cp == NULL || line[0] == '#') 665 continue; |
609 /* first, try a standard gethostbyname() */ 610 if ((hp = gethostbyname(cp)) == NULL) | 666 667 hints.ai_flags = 0; 668 hints.ai_family = AF_UNSPEC; 669 hints.ai_flags = AI_PASSIVE; 670 error = getaddrinfo(cp, NULL, &hints, &res); 671 if (error != NULL) |
611 continue; | 672 continue; |
673 for (ai = res; ai != NULL && ai->ai_addr != NULL; 674 ai = ai->ai_next) 675 { 676 |
|
612 for (hrp = firsthost; hrp != NULL; hrp = hrp->next) { 613 if (memcmp(&hrp->hostaddr, | 677 for (hrp = firsthost; hrp != NULL; hrp = hrp->next) { 678 if (memcmp(&hrp->hostaddr, |
614 hp->h_addr_list[0], 615 sizeof(hrp->hostaddr)) == 0) | 679 ai->ai_addr, 680 ai->ai_addr->sa_len) == 0) |
616 break; 617 } 618 if (hrp == NULL) { 619 if ((hrp = malloc(sizeof(struct ftphost))) == NULL) 620 continue; 621 /* defaults */ 622 hrp->statfile = _PATH_FTPDSTATFILE; 623 hrp->welcome = _PATH_FTPWELCOME; 624 hrp->loginmsg = _PATH_FTPLOGINMESG; 625 hrp->anonuser = "ftp"; 626 hrp->next = NULL; 627 lhrp->next = hrp; 628 lhrp = hrp; 629 } 630 (void) memcpy(&hrp->hostaddr, | 681 break; 682 } 683 if (hrp == NULL) { 684 if ((hrp = malloc(sizeof(struct ftphost))) == NULL) 685 continue; 686 /* defaults */ 687 hrp->statfile = _PATH_FTPDSTATFILE; 688 hrp->welcome = _PATH_FTPWELCOME; 689 hrp->loginmsg = _PATH_FTPLOGINMESG; 690 hrp->anonuser = "ftp"; 691 hrp->next = NULL; 692 lhrp->next = hrp; 693 lhrp = hrp; 694 } 695 (void) memcpy(&hrp->hostaddr, |
631 hp->h_addr_list[0], 632 sizeof(hrp->hostaddr)); | 696 ai->ai_addr, 697 ai->ai_addr->sa_len); |
633 /* 634 * determine hostname to use. | 698 /* 699 * determine hostname to use. |
635 * force defined name if it is a valid alias | 700 * force defined name if there is a valid alias |
636 * otherwise fallback to primary hostname 637 */ | 701 * otherwise fallback to primary hostname 702 */ |
638 if ((hp = gethostbyaddr((char*)&hrp->hostaddr, 639 sizeof(hrp->hostaddr), 640 AF_INET)) != NULL) { | 703 /* XXX: getaddrinfo() can't do alias check */ 704 switch(hrp->hostaddr.su_family) { 705 case AF_INET: 706 addr = &((struct sockaddr_in *)&hrp->hostaddr)->sin_addr; 707 addrsize = sizeof(struct sockaddr_in); 708 break; 709 case AF_INET6: 710 addr = &((struct sockaddr_in6 *)&hrp->hostaddr)->sin6_addr; 711 addrsize = sizeof(struct sockaddr_in6); 712 break; 713 default: 714 /* should not reach here */ 715 free(hrp); 716 continue; 717 /* NOTREACHED */ 718 } 719 if ((hp = getipnodebyaddr((char*)addr, addrsize, 720 hrp->hostaddr.su_family, 721 &hp_error)) != NULL) { |
641 if (strcmp(cp, hp->h_name) != 0) { 642 if (hp->h_aliases == NULL) 643 cp = hp->h_name; 644 else { 645 i = 0; 646 while (hp->h_aliases[i] && 647 strcmp(cp, hp->h_aliases[i]) != 0) 648 ++i; 649 if (hp->h_aliases[i] == NULL) 650 cp = hp->h_name; 651 } 652 } 653 } 654 hrp->hostname = strdup(cp); | 722 if (strcmp(cp, hp->h_name) != 0) { 723 if (hp->h_aliases == NULL) 724 cp = hp->h_name; 725 else { 726 i = 0; 727 while (hp->h_aliases[i] && 728 strcmp(cp, hp->h_aliases[i]) != 0) 729 ++i; 730 if (hp->h_aliases[i] == NULL) 731 cp = hp->h_name; 732 } 733 } 734 } 735 hrp->hostname = strdup(cp); |
736 freehostent(hp); |
|
655 /* ok, now we now peel off the rest */ 656 i = 0; 657 while (i < 4 && (cp = strtok(NULL, " \t")) != NULL) { 658 if (*cp != '-' && (cp = strdup(cp)) != NULL) { 659 switch (i) { 660 case 0: /* anon user permissions */ 661 hrp->anonuser = cp; 662 break; --- 5 unchanged lines hidden (view full) --- 668 break; 669 case 3: /* login message */ 670 hrp->loginmsg = cp; 671 break; 672 } 673 } 674 ++i; 675 } | 737 /* ok, now we now peel off the rest */ 738 i = 0; 739 while (i < 4 && (cp = strtok(NULL, " \t")) != NULL) { 740 if (*cp != '-' && (cp = strdup(cp)) != NULL) { 741 switch (i) { 742 case 0: /* anon user permissions */ 743 hrp->anonuser = cp; 744 break; --- 5 unchanged lines hidden (view full) --- 750 break; 751 case 3: /* login message */ 752 hrp->loginmsg = cp; 753 break; 754 } 755 } 756 ++i; 757 } |
758 /* XXX: re-initialization for getaddrinfo() loop */ 759 cp = strtok(line, " \t"); 760 } |
|
676 } 677 (void) fclose(fp); 678 } 679} 680 681static void | 761 } 762 (void) fclose(fp); 763 } 764} 765 766static void |
682selecthost(a) 683 struct in_addr *a; | 767selecthost(su) 768 union sockunion *su; |
684{ 685 struct ftphost *hrp; | 769{ 770 struct ftphost *hrp; |
771 u_int16_t port; 772#ifdef INET6 773 struct in6_addr *mapped_in6 = NULL; 774#endif |
|
686 | 775 |
776#ifdef INET6 777 /* 778 * XXX IPv4 mapped IPv6 addr consideraton, 779 * specified in rfc2373. 780 */ 781 if (su->su_family == AF_INET6 && 782 IN6_IS_ADDR_V4MAPPED(&su->su_sin6.sin6_addr)) 783 mapped_in6 = &su->su_sin6.sin6_addr; 784#endif 785 |
|
687 hrp = thishost = firsthost; /* default */ | 786 hrp = thishost = firsthost; /* default */ |
787 port = su->su_port; 788 su->su_port = 0; |
|
688 while (hrp != NULL) { | 789 while (hrp != NULL) { |
689 if (memcmp(a, &hrp->hostaddr, sizeof(hrp->hostaddr)) == 0) { | 790 if (memcmp(su, &hrp->hostaddr, sizeof(hrp->hostaddr)) == 0) { |
690 thishost = hrp; 691 break; 692 } | 791 thishost = hrp; 792 break; 793 } |
794#ifdef INET6 795 /* XXX IPv4 mapped IPv6 addr consideraton */ 796 if (hrp->hostaddr.su_family == AF_INET && mapped_in6 != NULL && 797 (memcmp(&mapped_in6->s6_addr[12], 798 &hrp->hostaddr.su_sin.sin_addr, 799 sizeof(struct in_addr)) == 0)) { 800 thishost = hrp; 801 break; 802 } 803#endif |
|
693 hrp = hrp->next; 694 } | 804 hrp = hrp->next; 805 } |
806 su->su_port = port; |
|
695 /* setup static variables as appropriate */ 696 hostname = thishost->hostname; 697 ftpuser = thishost->anonuser; 698} 699#endif 700 701/* 702 * Helper function for sgetpwnam(). --- 399 unchanged lines hidden (view full) --- 1102 return; 1103 } 1104 /* May be overridden by login.conf */ 1105 (void) umask(defumask); 1106#ifdef LOGIN_CAP 1107 if ((lc = login_getpwclass(pw)) != NULL) { 1108 char remote_ip[MAXHOSTNAMELEN]; 1109 | 807 /* setup static variables as appropriate */ 808 hostname = thishost->hostname; 809 ftpuser = thishost->anonuser; 810} 811#endif 812 813/* 814 * Helper function for sgetpwnam(). --- 399 unchanged lines hidden (view full) --- 1214 return; 1215 } 1216 /* May be overridden by login.conf */ 1217 (void) umask(defumask); 1218#ifdef LOGIN_CAP 1219 if ((lc = login_getpwclass(pw)) != NULL) { 1220 char remote_ip[MAXHOSTNAMELEN]; 1221 |
1110 strncpy(remote_ip, inet_ntoa(his_addr.sin_addr), 1111 sizeof(remote_ip) - 1); | 1222 getnameinfo((struct sockaddr *)&his_addr, his_addr.su_len, 1223 remote_ip, sizeof(remote_ip) - 1, NULL, 0, 1224 NI_NUMERICHOST|NI_WITHSCOPEID); |
1112 remote_ip[sizeof(remote_ip) - 1] = 0; 1113 if (!auth_hostok(lc, remotehost, remote_ip)) { 1114 syslog(LOG_INFO|LOG_AUTH, 1115 "FTP LOGIN FAILED (HOST) as %s: permission denied.", 1116 pw->pw_name); 1117 reply(530, "Permission denied.\n"); 1118 pw = NULL; 1119 return; --- 277 unchanged lines hidden (view full) --- 1397getdatasock(mode) 1398 char *mode; 1399{ 1400 int on = 1, s, t, tries; 1401 1402 if (data >= 0) 1403 return (fdopen(data, mode)); 1404 (void) seteuid((uid_t)0); | 1225 remote_ip[sizeof(remote_ip) - 1] = 0; 1226 if (!auth_hostok(lc, remotehost, remote_ip)) { 1227 syslog(LOG_INFO|LOG_AUTH, 1228 "FTP LOGIN FAILED (HOST) as %s: permission denied.", 1229 pw->pw_name); 1230 reply(530, "Permission denied.\n"); 1231 pw = NULL; 1232 return; --- 277 unchanged lines hidden (view full) --- 1510getdatasock(mode) 1511 char *mode; 1512{ 1513 int on = 1, s, t, tries; 1514 1515 if (data >= 0) 1516 return (fdopen(data, mode)); 1517 (void) seteuid((uid_t)0); |
1405 s = socket(AF_INET, SOCK_STREAM, 0); | 1518 1519 s = socket(data_dest.su_family, SOCK_STREAM, 0); |
1406 if (s < 0) 1407 goto bad; 1408 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, 1409 (char *) &on, sizeof(on)) < 0) 1410 goto bad; 1411 /* anchor socket to avoid multi-homing problems */ | 1520 if (s < 0) 1521 goto bad; 1522 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, 1523 (char *) &on, sizeof(on)) < 0) 1524 goto bad; 1525 /* anchor socket to avoid multi-homing problems */ |
1412 data_source.sin_len = sizeof(struct sockaddr_in); 1413 data_source.sin_family = AF_INET; 1414 data_source.sin_addr = ctrl_addr.sin_addr; | 1526 data_source = ctrl_addr; 1527 data_source.su_port = htons(20); /* ftp-data port */ |
1415 for (tries = 1; ; tries++) { 1416 if (bind(s, (struct sockaddr *)&data_source, | 1528 for (tries = 1; ; tries++) { 1529 if (bind(s, (struct sockaddr *)&data_source, |
1417 sizeof(data_source)) >= 0) | 1530 data_source.su_len) >= 0) |
1418 break; 1419 if (errno != EADDRINUSE || tries > 10) 1420 goto bad; 1421 sleep(tries); 1422 } 1423 (void) seteuid((uid_t)pw->pw_uid); 1424#ifdef IP_TOS | 1531 break; 1532 if (errno != EADDRINUSE || tries > 10) 1533 goto bad; 1534 sleep(tries); 1535 } 1536 (void) seteuid((uid_t)pw->pw_uid); 1537#ifdef IP_TOS |
1538 if (data_source.su_family == AF_INET) 1539 { |
|
1425 on = IPTOS_THROUGHPUT; 1426 if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0) 1427 syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); | 1540 on = IPTOS_THROUGHPUT; 1541 if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0) 1542 syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); |
1543 } |
|
1428#endif 1429#ifdef TCP_NOPUSH 1430 /* 1431 * Turn off push flag to keep sender TCP from sending short packets 1432 * at the boundaries of each write(). Should probably do a SO_SNDBUF 1433 * to set the send buffer size as well, but that may not be desirable 1434 * in heavy-load situations. 1435 */ --- 29 unchanged lines hidden (view full) --- 1465 1466 file_size = size; 1467 byte_count = 0; 1468 if (size != (off_t) -1) 1469 (void) snprintf(sizebuf, sizeof(sizebuf), " (%qd bytes)", size); 1470 else 1471 *sizebuf = '\0'; 1472 if (pdata >= 0) { | 1544#endif 1545#ifdef TCP_NOPUSH 1546 /* 1547 * Turn off push flag to keep sender TCP from sending short packets 1548 * at the boundaries of each write(). Should probably do a SO_SNDBUF 1549 * to set the send buffer size as well, but that may not be desirable 1550 * in heavy-load situations. 1551 */ --- 29 unchanged lines hidden (view full) --- 1581 1582 file_size = size; 1583 byte_count = 0; 1584 if (size != (off_t) -1) 1585 (void) snprintf(sizebuf, sizeof(sizebuf), " (%qd bytes)", size); 1586 else 1587 *sizebuf = '\0'; 1588 if (pdata >= 0) { |
1473 struct sockaddr_in from; 1474 int s, fromlen = sizeof(from); | 1589 union sockunion from; 1590 int s, fromlen = ctrl_addr.su_len; |
1475 struct timeval timeout; 1476 fd_set set; 1477 1478 FD_ZERO(&set); 1479 FD_SET(pdata, &set); 1480 1481 timeout.tv_usec = 0; 1482 timeout.tv_sec = 120; 1483 1484 if (select(pdata+1, &set, (fd_set *) 0, (fd_set *) 0, &timeout) == 0 || 1485 (s = accept(pdata, (struct sockaddr *) &from, &fromlen)) < 0) { 1486 reply(425, "Can't open data connection."); 1487 (void) close(pdata); 1488 pdata = -1; 1489 return (NULL); 1490 } 1491 (void) close(pdata); 1492 pdata = s; 1493#ifdef IP_TOS | 1591 struct timeval timeout; 1592 fd_set set; 1593 1594 FD_ZERO(&set); 1595 FD_SET(pdata, &set); 1596 1597 timeout.tv_usec = 0; 1598 timeout.tv_sec = 120; 1599 1600 if (select(pdata+1, &set, (fd_set *) 0, (fd_set *) 0, &timeout) == 0 || 1601 (s = accept(pdata, (struct sockaddr *) &from, &fromlen)) < 0) { 1602 reply(425, "Can't open data connection."); 1603 (void) close(pdata); 1604 pdata = -1; 1605 return (NULL); 1606 } 1607 (void) close(pdata); 1608 pdata = s; 1609#ifdef IP_TOS |
1610 if (from.su_family == AF_INET) 1611 { |
|
1494 tos = IPTOS_THROUGHPUT; 1495 (void) setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, 1496 sizeof(int)); | 1612 tos = IPTOS_THROUGHPUT; 1613 (void) setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, 1614 sizeof(int)); |
1615 } |
|
1497#endif 1498 reply(150, "Opening %s mode data connection for '%s'%s.", 1499 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); 1500 return (fdopen(pdata, mode)); 1501 } 1502 if (data >= 0) { 1503 reply(125, "Using existing data connection for '%s'%s.", 1504 name, sizebuf); 1505 usedefault = 1; 1506 return (fdopen(data, mode)); 1507 } 1508 if (usedefault) 1509 data_dest = his_addr; 1510 usedefault = 1; 1511 file = getdatasock(mode); 1512 if (file == NULL) { | 1616#endif 1617 reply(150, "Opening %s mode data connection for '%s'%s.", 1618 type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); 1619 return (fdopen(pdata, mode)); 1620 } 1621 if (data >= 0) { 1622 reply(125, "Using existing data connection for '%s'%s.", 1623 name, sizebuf); 1624 usedefault = 1; 1625 return (fdopen(data, mode)); 1626 } 1627 if (usedefault) 1628 data_dest = his_addr; 1629 usedefault = 1; 1630 file = getdatasock(mode); 1631 if (file == NULL) { |
1513 reply(425, "Can't create data socket (%s,%d): %s.", 1514 inet_ntoa(data_source.sin_addr), 1515 ntohs(data_source.sin_port), strerror(errno)); | 1632 char hostbuf[BUFSIZ], portbuf[BUFSIZ]; 1633 getnameinfo((struct sockaddr *)&data_source, 1634 data_source.su_len, hostbuf, sizeof(hostbuf) - 1, 1635 portbuf, sizeof(portbuf), 1636 NI_NUMERICHOST|NI_NUMERICSERV|NI_WITHSCOPEID); 1637 reply(425, "Can't create data socket (%s,%s): %s.", 1638 hostbuf, portbuf, strerror(errno)); |
1516 return (NULL); 1517 } 1518 data = fileno(file); 1519 while (connect(data, (struct sockaddr *)&data_dest, | 1639 return (NULL); 1640 } 1641 data = fileno(file); 1642 while (connect(data, (struct sockaddr *)&data_dest, |
1520 sizeof(data_dest)) < 0) { | 1643 data_dest.su_len) < 0) { |
1521 if (errno == EADDRINUSE && retry < swaitmax) { 1522 sleep((unsigned) swaitint); 1523 retry += swaitint; 1524 continue; 1525 } 1526 perror_reply(425, "Can't build data connection"); 1527 (void) fclose(file); 1528 data = -1; --- 234 unchanged lines hidden (view full) --- 1763 } 1764 (void) ftpd_pclose(fin); 1765 reply(211, "End of Status"); 1766} 1767 1768void 1769statcmd() 1770{ | 1644 if (errno == EADDRINUSE && retry < swaitmax) { 1645 sleep((unsigned) swaitint); 1646 retry += swaitint; 1647 continue; 1648 } 1649 perror_reply(425, "Can't build data connection"); 1650 (void) fclose(file); 1651 data = -1; --- 234 unchanged lines hidden (view full) --- 1886 } 1887 (void) ftpd_pclose(fin); 1888 reply(211, "End of Status"); 1889} 1890 1891void 1892statcmd() 1893{ |
1771 struct sockaddr_in *sin; | 1894 union sockunion *su; |
1772 u_char *a, *p; | 1895 u_char *a, *p; |
1896 char hname[INET6_ADDRSTRLEN]; 1897 int ispassive; |
|
1773 1774 lreply(211, "%s FTP server status:", hostname, version); 1775 printf(" %s\r\n", version); 1776 printf(" Connected to %s", remotehost); | 1898 1899 lreply(211, "%s FTP server status:", hostname, version); 1900 printf(" %s\r\n", version); 1901 printf(" Connected to %s", remotehost); |
1777 if (!isdigit(remotehost[0])) 1778 printf(" (%s)", inet_ntoa(his_addr.sin_addr)); | 1902 if (!getnameinfo((struct sockaddr *)&his_addr, his_addr.su_len, 1903 hname, sizeof(hname) - 1, NULL, 0, 1904 NI_NUMERICHOST|NI_WITHSCOPEID)) { 1905 if (strcmp(hname, remotehost) != 0) 1906 printf(" (%s)", hname); 1907 } |
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"); --- 8 unchanged lines hidden (view full) --- 1795#else 1796 printf(" %d", bytesize); /* need definition! */ 1797#endif 1798 printf("; STRUcture: %s; transfer MODE: %s\r\n", 1799 strunames[stru], modenames[mode]); 1800 if (data != -1) 1801 printf(" Data connection open\r\n"); 1802 else if (pdata != -1) { | 1908 printf("\r\n"); 1909 if (logged_in) { 1910 if (guest) 1911 printf(" Logged in anonymously\r\n"); 1912 else 1913 printf(" Logged in as %s\r\n", pw->pw_name); 1914 } else if (askpasswd) 1915 printf(" Waiting for password\r\n"); --- 8 unchanged lines hidden (view full) --- 1924#else 1925 printf(" %d", bytesize); /* need definition! */ 1926#endif 1927 printf("; STRUcture: %s; transfer MODE: %s\r\n", 1928 strunames[stru], modenames[mode]); 1929 if (data != -1) 1930 printf(" Data connection open\r\n"); 1931 else if (pdata != -1) { |
1803 printf(" in Passive mode"); 1804 sin = &pasv_addr; | 1932 ispassive = 1; 1933 su = &pasv_addr; |
1805 goto printaddr; 1806 } else if (usedefault == 0) { | 1934 goto printaddr; 1935 } else if (usedefault == 0) { |
1807 printf(" PORT"); 1808 sin = &data_dest; | 1936 ispassive = 0; 1937 su = &data_dest; |
1809printaddr: | 1938printaddr: |
1810 a = (u_char *) &sin->sin_addr; 1811 p = (u_char *) &sin->sin_port; | |
1812#define UC(b) (((int) b) & 0xff) | 1939#define UC(b) (((int) b) & 0xff) |
1813 printf(" (%d,%d,%d,%d,%d,%d)\r\n", UC(a[0]), 1814 UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1])); | 1940 if (epsvall) { 1941 printf(" EPSV only mode (EPSV ALL)\r\n"); 1942 goto epsvonly; 1943 } 1944 1945 /* PORT/PASV */ 1946 if (su->su_family == AF_INET) { 1947 a = (u_char *) &su->su_sin.sin_addr; 1948 p = (u_char *) &su->su_sin.sin_port; 1949 printf(" %s (%d,%d,%d,%d,%d,%d)\r\n", 1950 ispassive ? "PASV" : "PORT", 1951 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), 1952 UC(p[0]), UC(p[1])); 1953 } 1954 1955 /* LPRT/LPSV */ 1956 { 1957 int alen, af, i; 1958 1959 switch (su->su_family) { 1960 case AF_INET: 1961 a = (u_char *) &su->su_sin.sin_addr; 1962 p = (u_char *) &su->su_sin.sin_port; 1963 alen = sizeof(su->su_sin.sin_addr); 1964 af = 4; 1965 break; 1966 case AF_INET6: 1967 a = (u_char *) &su->su_sin6.sin6_addr; 1968 p = (u_char *) &su->su_sin6.sin6_port; 1969 alen = sizeof(su->su_sin6.sin6_addr); 1970 af = 6; 1971 break; 1972 default: 1973 af = 0; 1974 break; 1975 } 1976 if (af) { 1977 printf(" %s (%d,%d,", ispassive ? "LPSV" : "LPRT", 1978 af, alen); 1979 for (i = 0; i < alen; i++) 1980 printf("%d,", UC(a[i])); 1981 printf("%d,%d,%d)\r\n", 2, UC(p[0]), UC(p[1])); 1982 } 1983 } 1984 1985epsvonly:; 1986 /* EPRT/EPSV */ 1987 { 1988 int af; 1989 1990 switch (su->su_family) { 1991 case AF_INET: 1992 af = 1; 1993 break; 1994 case AF_INET6: 1995 af = 2; 1996 break; 1997 default: 1998 af = 0; 1999 break; 2000 } 2001 if (af) { 2002 if (!getnameinfo((struct sockaddr *)su, su->su_len, 2003 hname, sizeof(hname) - 1, NULL, 0, 2004 NI_NUMERICHOST)) { 2005 printf(" %s |%d|%s|%d|\r\n", 2006 ispassive ? "EPSV" : "EPRT", 2007 af, hname, htons(su->su_port)); 2008 } 2009 } 2010 } |
1815#undef UC 1816 } else 1817 printf(" No data connection\r\n"); 1818 reply(211, "End of status"); 1819} 1820 1821void 1822fatal(s) --- 187 unchanged lines hidden (view full) --- 2010 2011 if (rename(from, to) < 0) 2012 perror_reply(550, "rename"); 2013 else 2014 ack("RNTO"); 2015} 2016 2017static void | 2011#undef UC 2012 } else 2013 printf(" No data connection\r\n"); 2014 reply(211, "End of status"); 2015} 2016 2017void 2018fatal(s) --- 187 unchanged lines hidden (view full) --- 2206 2207 if (rename(from, to) < 0) 2208 perror_reply(550, "rename"); 2209 else 2210 ack("RNTO"); 2211} 2212 2213static void |
2018dolog(sin) 2019 struct sockaddr_in *sin; | 2214dolog(who) 2215 struct sockaddr *who; |
2020{ | 2216{ |
2021 realhostname(remotehost, sizeof(remotehost) - 1, &sin->sin_addr); | 2217 int error; |
2022 | 2218 |
2219 realhostname_sa(remotehost, sizeof(remotehost) - 1, who, who->sa_len); 2220 |
|
2023#ifdef SETPROCTITLE 2024#ifdef VIRTUAL_HOSTING 2025 if (thishost != firsthost) 2026 snprintf(proctitle, sizeof(proctitle), "%s: connected (to %s)", 2027 remotehost, hostname); 2028 else 2029#endif 2030 snprintf(proctitle, sizeof(proctitle), "%s: connected", 2031 remotehost); 2032 setproctitle("%s", proctitle); 2033#endif /* SETPROCTITLE */ 2034 2035 if (logging) { 2036#ifdef VIRTUAL_HOSTING 2037 if (thishost != firsthost) 2038 syslog(LOG_INFO, "connection from %s (to %s)", 2039 remotehost, hostname); 2040 else 2041#endif | 2221#ifdef SETPROCTITLE 2222#ifdef VIRTUAL_HOSTING 2223 if (thishost != firsthost) 2224 snprintf(proctitle, sizeof(proctitle), "%s: connected (to %s)", 2225 remotehost, hostname); 2226 else 2227#endif 2228 snprintf(proctitle, sizeof(proctitle), "%s: connected", 2229 remotehost); 2230 setproctitle("%s", proctitle); 2231#endif /* SETPROCTITLE */ 2232 2233 if (logging) { 2234#ifdef VIRTUAL_HOSTING 2235 if (thishost != firsthost) 2236 syslog(LOG_INFO, "connection from %s (to %s)", 2237 remotehost, hostname); 2238 else 2239#endif |
2240 { 2241 char who_name[MAXHOSTNAMELEN]; 2242 2243 error = getnameinfo(who, who->sa_len, 2244 who_name, sizeof(who_name) - 1, 2245 NULL, 0, 2246 NI_NUMERICHOST|NI_WITHSCOPEID); |
|
2042 syslog(LOG_INFO, "connection from %s (%s)", remotehost, | 2247 syslog(LOG_INFO, "connection from %s (%s)", remotehost, |
2043 inet_ntoa(sin->sin_addr)); | 2248 error == 0 ? who_name : ""); 2249 } |
2044 } 2045} 2046 2047/* 2048 * Record logout in wtmp file 2049 * and exit with supplied status. 2050 */ 2051void --- 55 unchanged lines hidden (view full) --- 2107passive() 2108{ 2109 int len; 2110 char *p, *a; 2111 2112 if (pdata >= 0) /* close old port if one set */ 2113 close(pdata); 2114 | 2250 } 2251} 2252 2253/* 2254 * Record logout in wtmp file 2255 * and exit with supplied status. 2256 */ 2257void --- 55 unchanged lines hidden (view full) --- 2313passive() 2314{ 2315 int len; 2316 char *p, *a; 2317 2318 if (pdata >= 0) /* close old port if one set */ 2319 close(pdata); 2320 |
2115 pdata = socket(AF_INET, SOCK_STREAM, 0); | 2321 pdata = socket(ctrl_addr.su_family, SOCK_STREAM, 0); |
2116 if (pdata < 0) { 2117 perror_reply(425, "Can't open passive connection"); 2118 return; 2119 } 2120 2121 (void) seteuid((uid_t)0); 2122 2123#ifdef IP_PORTRANGE | 2322 if (pdata < 0) { 2323 perror_reply(425, "Can't open passive connection"); 2324 return; 2325 } 2326 2327 (void) seteuid((uid_t)0); 2328 2329#ifdef IP_PORTRANGE |
2124 { | 2330 if (ctrl_addr.su_family == AF_INET) { |
2125 int on = restricted_data_ports ? IP_PORTRANGE_HIGH 2126 : IP_PORTRANGE_DEFAULT; 2127 2128 if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE, 2129 (char *)&on, sizeof(on)) < 0) 2130 goto pasv_error; 2131 } 2132#endif 2133 2134 pasv_addr = ctrl_addr; | 2331 int on = restricted_data_ports ? IP_PORTRANGE_HIGH 2332 : IP_PORTRANGE_DEFAULT; 2333 2334 if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE, 2335 (char *)&on, sizeof(on)) < 0) 2336 goto pasv_error; 2337 } 2338#endif 2339 2340 pasv_addr = ctrl_addr; |
2135 pasv_addr.sin_port = 0; 2136 if (bind(pdata, (struct sockaddr *)&pasv_addr, 2137 sizeof(pasv_addr)) < 0) | 2341 pasv_addr.su_port = 0; 2342 if (bind(pdata, (struct sockaddr *)&pasv_addr, pasv_addr.su_len) < 0) |
2138 goto pasv_error; 2139 2140 (void) seteuid((uid_t)pw->pw_uid); 2141 2142 len = sizeof(pasv_addr); 2143 if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0) 2144 goto pasv_error; 2145 if (listen(pdata, 1) < 0) 2146 goto pasv_error; | 2343 goto pasv_error; 2344 2345 (void) seteuid((uid_t)pw->pw_uid); 2346 2347 len = sizeof(pasv_addr); 2348 if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0) 2349 goto pasv_error; 2350 if (listen(pdata, 1) < 0) 2351 goto pasv_error; |
2147 a = (char *) &pasv_addr.sin_addr; 2148 p = (char *) &pasv_addr.sin_port; | 2352 if (pasv_addr.su_family == AF_INET) 2353 a = (char *) &pasv_addr.su_sin.sin_addr; 2354 else if (pasv_addr.su_family == AF_INET6 && 2355 IN6_IS_ADDR_V4MAPPED(&pasv_addr.su_sin6.sin6_addr)) 2356 a = (char *) &pasv_addr.su_sin6.sin6_addr.s6_addr[12]; 2357 else 2358 goto pasv_error; 2359 2360 p = (char *) &pasv_addr.su_port; |
2149 2150#define UC(b) (((int) b) & 0xff) 2151 2152 reply(227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", UC(a[0]), 2153 UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1])); 2154 return; 2155 2156pasv_error: 2157 (void) seteuid((uid_t)pw->pw_uid); 2158 (void) close(pdata); 2159 pdata = -1; 2160 perror_reply(425, "Can't open passive connection"); 2161 return; 2162} 2163 2164/* | 2361 2362#define UC(b) (((int) b) & 0xff) 2363 2364 reply(227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", UC(a[0]), 2365 UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1])); 2366 return; 2367 2368pasv_error: 2369 (void) seteuid((uid_t)pw->pw_uid); 2370 (void) close(pdata); 2371 pdata = -1; 2372 perror_reply(425, "Can't open passive connection"); 2373 return; 2374} 2375 2376/* |
2377 * Long Passive defined in RFC 1639. 2378 * 228 Entering Long Passive Mode 2379 * (af, hal, h1, h2, h3,..., pal, p1, p2...) 2380 */ 2381 2382void 2383long_passive(cmd, pf) 2384 char *cmd; 2385 int pf; 2386{ 2387 int len; 2388 char *p, *a; 2389 2390 if (pdata >= 0) /* close old port if one set */ 2391 close(pdata); 2392 2393 if (pf != PF_UNSPEC) { 2394 if (ctrl_addr.su_family != pf) { 2395 switch (ctrl_addr.su_family) { 2396 case AF_INET: 2397 pf = 1; 2398 break; 2399 case AF_INET6: 2400 pf = 2; 2401 break; 2402 default: 2403 pf = 0; 2404 break; 2405 } 2406 /* 2407 * XXX 2408 * only EPRT/EPSV ready clients will understand this 2409 */ 2410 if (strcmp(cmd, "EPSV") == 0 && pf) { 2411 reply(522, "Network protocol mismatch, " 2412 "use (%d)", pf); 2413 } else 2414 reply(501, "Network protocol mismatch"); /*XXX*/ 2415 2416 return; 2417 } 2418 } 2419 2420 pdata = socket(ctrl_addr.su_family, SOCK_STREAM, 0); 2421 if (pdata < 0) { 2422 perror_reply(425, "Can't open passive connection"); 2423 return; 2424 } 2425 2426 (void) seteuid((uid_t)0); 2427 2428 pasv_addr = ctrl_addr; 2429 pasv_addr.su_port = 0; 2430 len = pasv_addr.su_len; 2431 2432 if (bind(pdata, (struct sockaddr *)&pasv_addr, len) < 0) 2433 goto pasv_error; 2434 2435 (void) seteuid((uid_t)pw->pw_uid); 2436 2437 if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0) 2438 goto pasv_error; 2439 if (listen(pdata, 1) < 0) 2440 goto pasv_error; 2441 2442#define UC(b) (((int) b) & 0xff) 2443 2444 if (strcmp(cmd, "LPSV") == 0) { 2445 p = (char *)&pasv_addr.su_port; 2446 switch (pasv_addr.su_family) { 2447 case AF_INET: 2448 a = (char *) &pasv_addr.su_sin.sin_addr; 2449 v4_reply: 2450 reply(228, 2451"Entering Long Passive Mode (%d,%d,%d,%d,%d,%d,%d,%d,%d)", 2452 4, 4, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), 2453 2, UC(p[0]), UC(p[1])); 2454 return; 2455 case AF_INET6: 2456 if (IN6_IS_ADDR_V4MAPPED(&pasv_addr.su_sin6.sin6_addr)) { 2457 a = (char *) &pasv_addr.su_sin6.sin6_addr.s6_addr[12]; 2458 goto v4_reply; 2459 } 2460 a = (char *) &pasv_addr.su_sin6.sin6_addr; 2461 reply(228, 2462"Entering Long Passive Mode " 2463"(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)", 2464 6, 16, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), 2465 UC(a[4]), UC(a[5]), UC(a[6]), UC(a[7]), 2466 UC(a[8]), UC(a[9]), UC(a[10]), UC(a[11]), 2467 UC(a[12]), UC(a[13]), UC(a[14]), UC(a[15]), 2468 2, UC(p[0]), UC(p[1])); 2469 return; 2470 } 2471 } else if (strcmp(cmd, "EPSV") == 0) { 2472 switch (pasv_addr.su_family) { 2473 case AF_INET: 2474 case AF_INET6: 2475 reply(229, "Entering Extended Passive Mode (|||%d|)", 2476 ntohs(pasv_addr.su_port)); 2477 return; 2478 } 2479 } else { 2480 /* more proper error code? */ 2481 } 2482 2483pasv_error: 2484 (void) seteuid((uid_t)pw->pw_uid); 2485 (void) close(pdata); 2486 pdata = -1; 2487 perror_reply(425, "Can't open passive connection"); 2488 return; 2489} 2490 2491/* |
|
2165 * Generate unique name for file with basename "local". 2166 * The file named "local" is already known to exist. 2167 * Generates failure reply on error. 2168 */ 2169static char * 2170gunique(local) 2171 char *local; 2172{ --- 245 unchanged lines hidden --- | 2492 * Generate unique name for file with basename "local". 2493 * The file named "local" is already known to exist. 2494 * Generates failure reply on error. 2495 */ 2496static char * 2497gunique(local) 2498 char *local; 2499{ --- 245 unchanged lines hidden --- |