-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Package: gftp
Version: 2.0.19-2
Severity: important
When Passive Mode is not enabled, connecting gftp through a pure IPv6 FTP
session, the EPRT command is wrongly composed and fails to bind to
local host.
This leads to the inability to even get a file listing or a file down- or
upload.
The attached patch fixes the issue.
The patch need to be applied in the "gftp-2.0.19/lib" directory using the
command `patch -p2 /path/to/gftp-ipv6-dataconn2.patch`.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAlA/urEACgkQS4gT86VyyKqh5ACfRqvYydm2wCyeRy96MYjP4wZC
s0IAnR4CrWhMri9e1Q9F3F7w6fKtzr8X
=nF56
-----END PGP SIGNATURE-----
--- gftp-2.0.19/lib/rfc959.c 2008-03-04 13:02:48.000000000 +0100
+++ gftp-workingcopy/lib/rfc959.c 2012-08-30 20:47:33.000000000 +0200
@@ -863,7 +863,8 @@
rfc959_ipv6_data_connection_new (gftp_request * request)
{
struct sockaddr_in6 data_addr;
- char *pos, buf[64], *command;
+ socklen_t data_addr_len;
+ char *pos, addrstr[INET6_ADDRSTRLEN], *command;
intptr_t passive_transfer;
rfc959_parms * parms;
unsigned int port;
@@ -897,7 +898,8 @@
return (GFTP_EFATAL);
}
- memset (&data_addr, 0, sizeof (data_addr));
+ data_addr_len = sizeof(data_addr);
+ memset (&data_addr, 0, data_addr_len);
data_addr.sin6_family = AF_INET6;
gftp_lookup_request_option (request, "passive_transfer", &passive_transfer);
@@ -950,11 +952,20 @@
}
else
{
- memcpy (&data_addr, request->remote_addr, request->remote_addr_len);
- data_addr.sin6_port = 0;
+ if (getsockname (request->datafd, (struct sockaddr *) &data_addr,
+ &data_addr_len) == -1)
+ {
+ request->logging_function (gftp_logging_error, request,
+ _("Cannot get socket name: %s\n"),
+ g_strerror (errno));
+ gftp_disconnect (request);
+ return (GFTP_ERETRYABLE);
+ }
+
+ data_addr.sin6_port = 0;
if (bind (parms->data_connection, (struct sockaddr *) &data_addr,
- request->remote_addr_len) == -1)
+ data_addr_len) == -1)
{
request->logging_function (gftp_logging_error, request,
_("Cannot bind a port: %s\n"),
@@ -964,7 +975,7 @@
}
if (getsockname (parms->data_connection, (struct sockaddr *) &data_addr,
- &request->remote_addr_len) == -1)
+ &data_addr_len) == -1)
{
request->logging_function (gftp_logging_error, request,
_("Cannot get socket name: %s\n"),
@@ -983,7 +994,7 @@
return (GFTP_ERETRYABLE);
}
- if (inet_ntop (AF_INET6, &data_addr.sin6_addr, buf, sizeof (buf)) == NULL)
+ if (inet_ntop (AF_INET6, &data_addr.sin6_addr, addrstr, INET6_ADDRSTRLEN) == NULL)
{
request->logging_function (gftp_logging_error, request,
_("Cannot get address of local socket: %s\n"),
@@ -992,7 +1003,7 @@
return (GFTP_ERETRYABLE);
}
- command = g_strdup_printf ("EPRT |2|%s|%d|\n", buf,
+ command = g_strdup_printf ("EPRT |2|%s|%d|\n", addrstr,
ntohs (data_addr.sin6_port));
resp = rfc959_send_command (request, command, -1, 1, 1);