-----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);

Reply via email to