e000aa4
From 548375b2122f83771dc0b8571f16e5b5adabba98 Mon Sep 17 00:00:00 2001
8167548
From: Martin Sehnoutka <msehnout@redhat.com>
e000aa4
Date: Wed, 7 Sep 2016 10:04:31 +0200
Ondřej Lysoněk 7c0626d
Subject: [PATCH 07/59] Make filename filters smarter.
8167548
e000aa4
In the original version vsftpd was not able to prevent
e000aa4
users from downloading for instance /etc/passwd by
e000aa4
defining filters such as deny_file=/etc/passwd or /etc*
e000aa4
or passwd. Example of erroneous behavior:
e000aa4
230 Login successful.
e000aa4
Remote system type is UNIX.
e000aa4
Using binary mode to transfer files.
e000aa4
ftp> cd /
e000aa4
250 Directory successfully changed.
e000aa4
ftp> cd /etc
e000aa4
550 Permission denied.
e000aa4
ftp> cd etc
e000aa4
250 Directory successfully changed.
e000aa4
ftp> get passwd
e000aa4
local: passwd remote: passwd
e000aa4
227 Entering Passive Mode (127,0,0,1,99,251)
e000aa4
150 Opening BINARY mode data connection for passwd (2813 bytes).
e000aa4
226 File send OK.
e000aa4
2813 bytes received in 0.00016 seconds (1.7e+04 Kbytes/s)
e000aa4
ftp> quit
e000aa4
221 Goodbye.
8167548
---
e000aa4
 ls.c  | 24 +++++++++++++++++++++++-
8167548
 str.c | 11 +++++++++++
8167548
 str.h |  1 +
e000aa4
 3 files changed, 35 insertions(+), 1 deletion(-)
8167548
8167548
diff --git a/ls.c b/ls.c
e000aa4
index 7e1376d..f489478 100644
8167548
--- a/ls.c
8167548
+++ b/ls.c
e000aa4
@@ -246,8 +246,30 @@ vsf_filename_passes_filter(const struct mystr* p_filename_str,
8e24fc9
   int ret = 0;
8e24fc9
   char last_token = 0;
8e24fc9
   int must_match_at_current_pos = 1;
e000aa4
+
e000aa4
+
8e24fc9
   str_copy(&filter_remain_str, p_filter_str);
8e24fc9
-  str_copy(&name_remain_str, p_filename_str);
e000aa4
+
8e24fc9
+  if (!str_isempty (&filter_remain_str) && !str_isempty(p_filename_str)) {
8e24fc9
+    if (str_get_char_at(p_filter_str, 0) == '/') {
8e24fc9
+      if (str_get_char_at(p_filename_str, 0) != '/') {
8e24fc9
+        str_getcwd (&name_remain_str);
e000aa4
+
8e24fc9
+        if (str_getlen(&name_remain_str) > 1) /* cwd != root dir */
8e24fc9
+          str_append_char (&name_remain_str, '/');
e000aa4
+
8e24fc9
+        str_append_str (&name_remain_str, p_filename_str);
8e24fc9
+      }
8e24fc9
+      else
8e24fc9
+       str_copy (&name_remain_str, p_filename_str);
8e24fc9
+    } else {
8e24fc9
+      if (str_get_char_at(p_filter_str, 0) != '{')
8e24fc9
+        str_basename (&name_remain_str, p_filename_str);
8e24fc9
+      else
8e24fc9
+        str_copy (&name_remain_str, p_filename_str);
8e24fc9
+    }
8e24fc9
+  } else
8e24fc9
+    str_copy(&name_remain_str, p_filename_str);
e000aa4
 
Jiri Skala 96a8543
   while (!str_isempty(&filter_remain_str) && *iters < VSFTP_MATCHITERS_MAX)
8e24fc9
   {
8167548
diff --git a/str.c b/str.c
8167548
index 6596204..ba4b92a 100644
8167548
--- a/str.c
8167548
+++ b/str.c
8167548
@@ -711,3 +711,14 @@ str_replace_unprintable(struct mystr* p_str, char new_char)
8e24fc9
   }
8e24fc9
 }
8e24fc9
 
8e24fc9
+void
8e24fc9
+str_basename (struct mystr* d_str, const struct mystr* path)
8e24fc9
+{
fe8522b
+  static struct mystr tmp;
8e24fc9
+
8e24fc9
+  str_copy (&tmp, path);
8e24fc9
+  str_split_char_reverse(&tmp, d_str, '/');
8e24fc9
+
8e24fc9
+  if (str_isempty(d_str))
8e24fc9
+   str_copy (d_str, path);
8e24fc9
+}
8167548
diff --git a/str.h b/str.h
8167548
index ab0a9a4..3a21b50 100644
8167548
--- a/str.h
8167548
+++ b/str.h
8167548
@@ -100,6 +100,7 @@ void str_replace_unprintable(struct mystr* p_str, char new_char);
3572541
 int str_atoi(const struct mystr* p_str);
3572541
 filesize_t str_a_to_filesize_t(const struct mystr* p_str);
3572541
 unsigned int str_octal_to_uint(const struct mystr* p_str);
3572541
+void str_basename (struct mystr* d_str, const struct mystr* path);
3572541
 
3572541
 /* PURPOSE: Extract a line of text (delimited by \n or EOF) from a string
3572541
  * buffer, starting at character position 'p_pos'. The extracted line will
8167548
-- 
Ondřej Lysoněk 7c0626d
2.14.4
8167548