summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Josefsson <simon@josefsson.org>2021-09-01 09:09:50 +0200
committerSimon Josefsson <simon@josefsson.org>2021-09-01 09:17:06 +0200
commit58cb043b190fd04effdaea7c9403416b436e50dd (patch)
tree86e685a59130dd59812164155b9edd9812bb2901
parent8586a5b3fe3302320b923ee31f9994e75708566e (diff)
downloadinetutils-58cb043b190fd04effdaea7c9403416b436e50dd.tar.gz
ftp: check that PASV/LSPV addresses match.
* NEWS: Mention change. * ftp/ftp.c (initconn): Validate returned addresses.
-rw-r--r--NEWS9
-rw-r--r--ftp/ftp.c21
2 files changed, 30 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index f2ac9ea..9cc42c0 100644
--- a/NEWS
+++ b/NEWS
@@ -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
diff --git a/ftp/ftp.c b/ftp/ftp.c
index d21dbdd..7513539 100644
--- a/ftp/ftp.c
+++ b/ftp/ftp.c
@@ -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
{