You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
qubes-linux-kernel/patches.fixes/netfilter-implement-rfc-112...

105 lines
3.7 KiB

From: Jeff Mahoney <jeffm@suse.com>
Subject: netfilter: Implement RFC 1123 for FTP conntrack
References: bnc#466279
Patch-mainline: Submitted via http://bugzilla.netfilter.org/show_bug.cgi?id=574 23 Jan 2011
The FTP conntrack code currently only accepts the following format for
the 227 response for PASV:
227 Entering Passive Mode (148,100,81,40,31,161).
It doesn't accept the following format from an obscure server:
227 Data transfer will passively listen to 67,218,99,134,50,144
From RFC 1123:
The format of the 227 reply to a PASV command is not
well standardized. In particular, an FTP client cannot
assume that the parentheses shown on page 40 of RFC-959
will be present (and in fact, Figure 3 on page 43 omits
them). Therefore, a User-FTP program that interprets
the PASV reply must scan the reply for the first digit
of the host and port numbers.
This patch adds support for the RFC 1123 clarification by:
- Allowing a search filter to specify NUL as the terminator so that
try_number will return successfully if the array of numbers has been
filled when an unexpected character is encountered.
- Using space as the separator for the 227 reply and then scanning for
the first digit of the number sequence. The number sequence is parsed
out using the existing try_rfc959 but with a NUL terminator.
Tracked in: https://bugzilla.novell.com/show_bug.cgi?id=466279
Reported-by: Mark Post <mpost@novell.com>
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
net/netfilter/nf_conntrack_ftp.c | 36 +++++++++++++++++++++++++++++++-----
1 file changed, 31 insertions(+), 5 deletions(-)
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -53,6 +53,7 @@ unsigned int (*nf_nat_ftp_hook)(struct s
EXPORT_SYMBOL_GPL(nf_nat_ftp_hook);
static int try_rfc959(const char *, size_t, struct nf_conntrack_man *, char);
+static int try_rfc1123(const char *, size_t, struct nf_conntrack_man *, char);
static int try_eprt(const char *, size_t, struct nf_conntrack_man *, char);
static int try_epsv_response(const char *, size_t, struct nf_conntrack_man *,
char);
@@ -87,10 +88,10 @@ static struct ftp_search {
{
.pattern = "227 ",
.plen = sizeof("227 ") - 1,
- .skip = '(',
- .term = ')',
+ .skip = ' ',
+ .term = '\0',
.ftptype = NF_CT_FTP_PASV,
- .getnum = try_rfc959,
+ .getnum = try_rfc1123,
},
{
.pattern = "229 ",
@@ -129,8 +130,9 @@ static int try_number(const char *data,
i++;
else {
/* Unexpected character; true if it's the
- terminator and we're finished. */
- if (*data == term && i == array_size - 1)
+ terminator (or we don't care about one)
+ and we're finished. */
+ if ((*data == term || !term) && i == array_size - 1)
return len;
pr_debug("Char %u (got %u nums) `%u' unexpected\n",
@@ -160,6 +162,30 @@ static int try_rfc959(const char *data,
return length;
}
+/*
+ * From RFC 1123:
+ * The format of the 227 reply to a PASV command is not
+ * well standardized. In particular, an FTP client cannot
+ * assume that the parentheses shown on page 40 of RFC-959
+ * will be present (and in fact, Figure 3 on page 43 omits
+ * them). Therefore, a User-FTP program that interprets
+ * the PASV reply must scan the reply for the first digit
+ * of the host and port numbers.
+ */
+static int try_rfc1123(const char *data, size_t dlen,
+ struct nf_conntrack_man *cmd, char term)
+{
+ int i;
+ for (i = 0; i < dlen; i++)
+ if (isdigit(data[i]))
+ break;
+
+ if (i == dlen)
+ return 0;
+
+ return try_rfc959(data + i, dlen - i, cmd, 0);
+}
+
/* Grab port: number up to delimiter */
static int get_port(const char *data, int start, size_t dlen, char delim,
__be16 *port)