diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-16 19:54:06 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-16 19:54:06 +0000 |
| commit | 43bb7bba3b09f9beddb07417fa4997a599f5c6d1 (patch) | |
| tree | 844f7ccd64e36b0855c47246e88614c696561cc7 | |
| parent | 20c82168976a511237b45eef94891e9124f47f7a (diff) | |
| download | busybox-w32-43bb7bba3b09f9beddb07417fa4997a599f5c6d1.tar.gz busybox-w32-43bb7bba3b09f9beddb07417fa4997a599f5c6d1.tar.bz2 busybox-w32-43bb7bba3b09f9beddb07417fa4997a599f5c6d1.zip | |
ftpd: simplify PORT check by assuming IP = peer's IP.
Should be as safe as before this change.
function old new delta
ftpd_main 2115 2025 -90
| -rw-r--r-- | networking/ftpd.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/networking/ftpd.c b/networking/ftpd.c index d63fd9bed..675324803 100644 --- a/networking/ftpd.c +++ b/networking/ftpd.c | |||
| @@ -422,21 +422,42 @@ handle_epsv(void) | |||
| 422 | free(response); | 422 | free(response); |
| 423 | } | 423 | } |
| 424 | 424 | ||
| 425 | /* libbb candidate */ | ||
| 426 | static | ||
| 427 | len_and_sockaddr* get_peer_lsa(int fd) | ||
| 428 | { | ||
| 429 | len_and_sockaddr *lsa; | ||
| 430 | socklen_t len = 0; | ||
| 431 | |||
| 432 | if (getpeername(fd, NULL, &len) != 0) | ||
| 433 | return NULL; | ||
| 434 | lsa = xzalloc(LSA_LEN_SIZE + len); | ||
| 435 | lsa->len = len; | ||
| 436 | getpeername(fd, &lsa->u.sa, &lsa->len); | ||
| 437 | return lsa; | ||
| 438 | } | ||
| 439 | |||
| 425 | static void | 440 | static void |
| 426 | handle_port(void) | 441 | handle_port(void) |
| 427 | { | 442 | { |
| 428 | unsigned port, port_hi; | 443 | unsigned port, port_hi; |
| 429 | char *raw, *comma; | 444 | char *raw, *comma; |
| 445 | #ifdef WHY_BOTHER_WE_CAN_ASSUME_IP_MATCHES | ||
| 430 | socklen_t peer_ipv4_len; | 446 | socklen_t peer_ipv4_len; |
| 431 | struct sockaddr_in peer_ipv4; | 447 | struct sockaddr_in peer_ipv4; |
| 432 | struct in_addr port_ipv4_sin_addr; | 448 | struct in_addr port_ipv4_sin_addr; |
| 449 | #endif | ||
| 433 | 450 | ||
| 434 | port_pasv_cleanup(); | 451 | port_pasv_cleanup(); |
| 435 | 452 | ||
| 436 | raw = G.ftp_arg; | 453 | raw = G.ftp_arg; |
| 437 | 454 | ||
| 438 | /* PORT command format makes sense only over IPv4 */ | 455 | /* PORT command format makes sense only over IPv4 */ |
| 439 | if (!raw || G.local_addr->u.sa.sa_family != AF_INET) { | 456 | if (!raw |
| 457 | #ifdef WHY_BOTHER_WE_CAN_ASSUME_IP_MATCHES | ||
| 458 | || G.local_addr->u.sa.sa_family != AF_INET | ||
| 459 | #endif | ||
| 460 | ) { | ||
| 440 | bail: | 461 | bail: |
| 441 | cmdio_write_error(FTP_BADCMD); | 462 | cmdio_write_error(FTP_BADCMD); |
| 442 | return; | 463 | return; |
| @@ -459,6 +480,7 @@ handle_port(void) | |||
| 459 | goto bail; | 480 | goto bail; |
| 460 | port |= port_hi << 8; | 481 | port |= port_hi << 8; |
| 461 | 482 | ||
| 483 | #ifdef WHY_BOTHER_WE_CAN_ASSUME_IP_MATCHES | ||
| 462 | replace_char(raw, ',', '.'); | 484 | replace_char(raw, ',', '.'); |
| 463 | 485 | ||
| 464 | /* We are verifying that PORT's IP matches getpeername(). | 486 | /* We are verifying that PORT's IP matches getpeername(). |
| @@ -477,6 +499,10 @@ handle_port(void) | |||
| 477 | goto bail; | 499 | goto bail; |
| 478 | 500 | ||
| 479 | G.port_addr = xdotted2sockaddr(raw, port); | 501 | G.port_addr = xdotted2sockaddr(raw, port); |
| 502 | #else | ||
| 503 | G.port_addr = get_peer_lsa(STDIN_FILENO); | ||
| 504 | set_nport(G.port_addr, port); | ||
| 505 | #endif | ||
| 480 | cmdio_write_ok(FTP_PORTOK); | 506 | cmdio_write_ok(FTP_PORTOK); |
| 481 | } | 507 | } |
| 482 | 508 | ||
