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