aboutsummaryrefslogtreecommitdiff
path: root/networking/ftpd.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-03-16 19:54:06 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-03-16 19:54:06 +0000
commit43bb7bba3b09f9beddb07417fa4997a599f5c6d1 (patch)
tree844f7ccd64e36b0855c47246e88614c696561cc7 /networking/ftpd.c
parent20c82168976a511237b45eef94891e9124f47f7a (diff)
downloadbusybox-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
Diffstat (limited to 'networking/ftpd.c')
-rw-r--r--networking/ftpd.c28
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 */
426static
427len_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
425static void 440static void
426handle_port(void) 441handle_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