Blame SOURCES/0007-Make-filename-filters-smarter.patch

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