Bug#808595: vsftpd: Restrict upload and download of files to certain name patterns

2015-12-21 Thread Jörg Frings-Fürst
Hello Thomas,

thank you for spending your time helping to make Debian better with
this bug report.


I have forward you patch to Chris Evans.


CU
Jörg

-- 
New:
GPG Fingerprint: 63E0 075F C8D4 3ABB 35AB  30EE 09F8 9F3C 8CA1 D25D
GPG key (long) : 09F89F3C8CA1D25D
GPG Key: 8CA1D25D
CAcert Key S/N : 0E:D4:56

Old pgp Key: BE581B6E (revoked since 2014-12-31).

Jörg Frings-Fürst
D-54526 Niederkail

Threema: SYR8SJXB

IRC: j_...@freenode.net
 j_...@oftc.net

My wish list: 
 - Please send me a picture from the nature at your home.





signature.asc
Description: This is a digitally signed message part


Bug#808595: vsftpd: Restrict upload and download of files to certain name patterns

2015-12-21 Thread Thomas B . Preußer
Source: vsftpd
Severity: wishlist
Tags: patch

Dear Maintainer,

vsftpd provides very basic name-based access control via the deny_file option.
Files with names matching a provided pattern cannot be targeted by any
operation other than a directory listing.

The provided patch allows to restrict file uploads and downloads using the
same simple pattern specification as deny_file and hide_file introducing the
new options upload_file and download_file. If these options are specified, a
file is only permitted to be up- or downloaded if its name matches the
corresponding pattern - in addition to not matching deny_file.

The provision of distinct filename patterns for up- and download is useful
in many use cases where the served files (e.g. configurations) are different
from the collected ones (e.g. status reports). Especially in the context of
legacy ftp without SSL-secured access, this avoids risking the server to be
misused as a data relay for third parties.

The provided patch:
 - introduces the new options upload_file and download_file,
   -> tunables.h, tunables.c, parseconf.c
 - provides corresonding access checkers,
   -> access.h, access.c
 - utilizes these access checkers in the corresponding operations, and
   -> postlogin.c
 - documents the new options in the manual page.
   -> vsftpd.conf.5

The patch has been generated on the git repo:
 - cloned on 2015-12-21 and
 - patched with all patches included under debian/patches/.

Thus, the patch should be applied after all other patches in the root of the
repo using:

  patch -p1 < upload_download_filename_pattern.patch


Description: Restrict upload and download of files to certain name patterns.
Author: Thomas B. Preußer 
Last-Update: 2015-12-21
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
===
Index:  access.c
access.h
parseconf.c
postlogin.c
tunables.c
tunables.h
vsftpd.conf.5

--- vsftpd.orig/access.c
+++ vsftpd/access.c
@@ -12,11 +12,27 @@
 #include "tunables.h"
 #include "str.h"
 
+static int
+vsf_match_filter(struct mystr const *const p_filename_str,
+struct mystr const *const p_access_str) {
+
+  unsigned  iters = 0;
+  if (vsf_filename_passes_filter(p_filename_str, p_access_str, &iters))
+  {
+return 1;
+  }
+  else
+  {
+struct str_locate_result const loc_res =
+  str_locate_str(p_filename_str, p_access_str);
+return  loc_res.found;
+  }
+}
+
 int
 vsf_access_check_file(const struct mystr* p_filename_str)
 {
   static struct mystr s_access_str;
-  unsigned int iters = 0;
 
   if (!tunable_deny_file)
   {
@@ -26,27 +42,21 @@
   {
 str_alloc_text(&s_access_str, tunable_deny_file);
   }
-  if (vsf_filename_passes_filter(p_filename_str, &s_access_str, &iters))
+
+  if (vsf_match_filter(p_filename_str, &s_access_str))
   {
 return 0;
   }
   else
   {
-struct str_locate_result loc_res =
-  str_locate_str(p_filename_str, &s_access_str);
-if (loc_res.found)
-{
-  return 0;
-}
+return 1;
   }
-  return 1;
 }
 
 int
 vsf_access_check_file_visible(const struct mystr* p_filename_str)
 {
   static struct mystr s_access_str;
-  unsigned int iters = 0;
 
   if (!tunable_hide_file)
   {
@@ -56,19 +66,47 @@
   {
 str_alloc_text(&s_access_str, tunable_hide_file);
   }
-  if (vsf_filename_passes_filter(p_filename_str, &s_access_str, &iters))
+
+  if (vsf_match_filter(p_filename_str, &s_access_str))
   {
 return 0;
   }
   else
   {
-struct str_locate_result loc_res =
-  str_locate_str(p_filename_str, &s_access_str);
-if (loc_res.found)
-{
-  return 0;
-}
+return 1;
+  }
+}
+
+int
+vsf_access_check_file_upload(const struct mystr* p_filename_str)
+{
+  static struct mystr s_access_str;
+
+  if (!tunable_upload_file)
+  {
+return 1;
+  }
+  if (str_isempty(&s_access_str))
+  {
+str_alloc_text(&s_access_str, tunable_upload_file);
   }
-  return 1;
+
+  return  vsf_match_filter(p_filename_str, &s_access_str);
 }
 
+int
+vsf_access_check_file_download(const struct mystr* p_filename_str)
+{
+  static struct mystr s_access_str;
+
+  if (!tunable_download_file)
+  {
+return 1;
+  }
+  if (str_isempty(&s_access_str))
+  {
+str_alloc_text(&s_access_str, tunable_download_file);
+  }
+
+  return  vsf_match_filter(p_filename_str, &s_access_str);
+}
--- vsftpd.orig/access.h
+++ vsftpd/access.h
@@ -25,5 +25,27 @@
  */
 int vsf_access_check_file_visible(const struct mystr* p_filename_str);
 
+/* vsf_access_check_file_upload()
+ * PURPOSE
+ * Check whether the current session has permission to upload a file
+ * using the given filename.
+ * PARAMETERS
+ * p_filename_str  - the filename to check upload permission for
+ * RETURNS
+ * Returns 1 if the file may be uploaded, otherwise 0.
+ */
+int vsf_access_check_file_upload(const struct mystr* p_filename_str);
+
+/* vsf_access_check_file_download()
+ * PURPOSE
+ * Check whether the