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

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