diff options
| author | Simon Josefsson <simon@josefsson.org> | 2021-09-01 09:09:50 +0200 |
|---|---|---|
| committer | Simon Josefsson <simon@josefsson.org> | 2021-09-01 09:17:06 +0200 |
| commit | 58cb043b190fd04effdaea7c9403416b436e50dd (patch) | |
| tree | 86e685a59130dd59812164155b9edd9812bb2901 | |
| parent | 8586a5b3fe3302320b923ee31f9994e75708566e (diff) | |
| download | inetutils-58cb043b190fd04effdaea7c9403416b436e50dd.tar.gz | |
ftp: check that PASV/LSPV addresses match.
* NEWS: Mention change.
* ftp/ftp.c (initconn): Validate returned addresses.
| -rw-r--r-- | NEWS | 9 | ||||
| -rw-r--r-- | ftp/ftp.c | 21 |
2 files changed, 30 insertions, 0 deletions
@@ -2,6 +2,15 @@ GNU inetutils NEWS -- history of user-visible changes. * Noteworthy changes in release ?.? (????-??-??) [?] +** ftp + +The ftp client now validate addresses returned by PASV/LSPV responses, +to make sure they match the server address. Reported by ZeddYu Lu in +<https://lists.gnu.org/archive/html/bug-inetutils/2021-06/msg00002.html>. + +Thanks to Luke Mewburn <lukem@netbsd.org> for discussion and fix to +NetBSD code, we used a similar solution. + ** logger ** rlogind @@ -1365,6 +1365,13 @@ initconn (void) uint32_t *pu32 = (uint32_t *) &data_addr_sa4->sin_addr.s_addr; pu32[0] = htonl ( (h[0] << 24) | (h[1] << 16) | (h[2] << 8) | h[3]); } + if (data_addr_sa4->sin_addr.s_addr + != ((struct sockaddr_in *) &hisctladdr)->sin_addr.s_addr) + { + printf ("Passive mode address mismatch.\n"); + (void) command ("ABOR"); /* Cancel any open connection. */ + goto bad; + } } /* LPSV IPv4 */ else /* IPv6 */ { @@ -1395,6 +1402,13 @@ initconn (void) pu32[2] = htonl ( (h[8] << 24) | (h[9] << 16) | (h[10] << 8) | h[11]); pu32[3] = htonl ( (h[12] << 24) | (h[13] << 16) | (h[14] << 8) | h[15]); } + if (data_addr_sa6->sin6_addr.s6_addr + != ((struct sockaddr_in6 *) &hisctladdr)->sin6_addr.s6_addr) + { + printf ("Passive mode address mismatch.\n"); + (void) command ("ABOR"); /* Cancel any open connection. */ + goto bad; + } } /* LPSV IPv6 */ } else /* !EPSV && !LPSV */ @@ -1415,6 +1429,13 @@ initconn (void) | ((a2 & 0xff) << 8) | (a3 & 0xff) ); data_addr_sa4->sin_port = htons (((p0 & 0xff) << 8) | (p1 & 0xff)); + if (data_addr_sa4->sin_addr.s_addr + != ((struct sockaddr_in *) &hisctladdr)->sin_addr.s_addr) + { + printf ("Passive mode address mismatch.\n"); + (void) command ("ABOR"); /* Cancel any open connection. */ + goto bad; + } } /* PASV */ else { |
