]> TLD Linux GIT Repositories - packages/vsftpd.git/commitdiff
- from PLD, updated to 3.0.3
authorMarcin Krol <hawk@tld-linux.org>
Wed, 13 Apr 2016 07:18:44 +0000 (07:18 +0000)
committerMarcin Krol <hawk@tld-linux.org>
Wed, 13 Apr 2016 07:18:44 +0000 (07:18 +0000)
vsftpd-amd64-findlibs.patch [new file with mode: 0644]
vsftpd-builddefs.patch [new file with mode: 0644]
vsftpd-clamav.patch [new file with mode: 0644]
vsftpd-findlibs-egrep.patch [new file with mode: 0644]
vsftpd-ftpusers [new file with mode: 0644]
vsftpd-switch_sha256_to_sha1.patch [new file with mode: 0644]
vsftpd-use-evp_sha1.patch [new file with mode: 0644]
vsftpd.inetd [new file with mode: 0644]
vsftpd.init [new file with mode: 0644]
vsftpd.pamd [new file with mode: 0644]
vsftpd.spec [new file with mode: 0644]

diff --git a/vsftpd-amd64-findlibs.patch b/vsftpd-amd64-findlibs.patch
new file mode 100644 (file)
index 0000000..67b22b4
--- /dev/null
@@ -0,0 +1,10 @@
+--- vsftpd-2.3.1/vsf_findlibs.sh~      2009-10-19 04:05:21.000000000 +0200
++++ vsftpd-2.3.1/vsf_findlibs.sh       2010-09-15 10:09:12.543414001 +0200
+@@ -13,7 +13,6 @@
+ # Look for PAM (done weirdly due to distribution bugs (e.g. Debian) or the
+ # crypt library.
+ if find_func pam_start sysdeputil.o; then
+-  locate_library /lib/libpam.so.0 && echo "/lib/libpam.so.0";
+   locate_library /usr/lib/libpam.so && echo "-lpam";
+   locate_library /usr/lib64/libpam.so && echo "-lpam";
+   # HP-UX ends shared libraries with .sl
diff --git a/vsftpd-builddefs.patch b/vsftpd-builddefs.patch
new file mode 100644 (file)
index 0000000..d350880
--- /dev/null
@@ -0,0 +1,14 @@
+--- vsftpd-2.0.0/builddefs.h.orig      2004-06-30 03:30:53.000000000 +0200
++++ vsftpd-2.0.0/builddefs.h   2004-07-02 09:33:54.694621160 +0200
+@@ -1,9 +1,9 @@
+ #ifndef VSF_BUILDDEFS_H
+ #define VSF_BUILDDEFS_H
+-#undef VSF_BUILD_TCPWRAPPERS
++#define VSF_BUILD_TCPWRAPPERS
+ #define VSF_BUILD_PAM
+-#undef VSF_BUILD_SSL
++#define VSF_BUILD_SSL
+ #endif /* VSF_BUILDDEFS_H */
diff --git a/vsftpd-clamav.patch b/vsftpd-clamav.patch
new file mode 100644 (file)
index 0000000..80cdbaa
--- /dev/null
@@ -0,0 +1,662 @@
+Add support for scanning uploaded files with clamav. Not all features are 
+implemented (ex. file inclusion/exclusion for scanning). Every uploaded file is
+saved in random named file, and moved to destination file after scanning. Side
+effects: when uploaded *new* file was infected, 0-size file left.
+
+Written by Marek Marczykowski <m.marczykowski@fiok.pl>
+
+diff -Naru vsftpd-2.2.2.orig/Makefile vsftpd-2.2.2/Makefile
+--- vsftpd-2.2.2.orig/Makefile 2009-05-22 21:44:52.000000000 +0200
++++ vsftpd-2.2.2/Makefile      2010-04-29 19:46:54.435448038 +0200
+@@ -14,7 +14,7 @@
+     banner.o filestr.o parseconf.o secutil.o \
+     ascii.o oneprocess.o twoprocess.o privops.o standalone.o hash.o \
+     tcpwrap.o ipaddrparse.o access.o features.o readwrite.o opts.o \
+-    ssl.o sslslave.o ptracesandbox.o ftppolicy.o sysutil.o sysdeputil.o
++    ssl.o sslslave.o ptracesandbox.o ftppolicy.o sysutil.o sysdeputil.o clamav.o
+ .c.o:
+diff -Naru vsftpd-2.2.2.orig/clamav.c vsftpd-2.2.2/clamav.c
+--- vsftpd-2.2.2.orig/clamav.c 1970-01-01 01:00:00.000000000 +0100
++++ vsftpd-2.2.2/clamav.c      2010-04-29 19:46:54.435448038 +0200
+@@ -0,0 +1,221 @@
++#include <sys/types.h>
++#include <regex.h>
++#include <sys/socket.h>
++#include <linux/un.h>
++#include <arpa/inet.h>
++#include <netdb.h>
++#include <sys/socket.h>
++#include <stdio.h>
++#include "clamav.h"
++#include "tunables.h"
++#include "utility.h"
++#include "sysutil.h"
++#include "logging.h"
++#include "sysstr.h"
++
++regex_t av_include_files_regex, av_exclude_files_regex;
++
++int av_init() {
++      int ret;
++
++      if (tunable_av_enable) {
++              if (tunable_av_include_files) {
++                      if ((ret=regcomp(&av_include_files_regex, tunable_av_include_files, REG_NOSUB)) != 0)
++                              die("regex compilation failed for AvIncludeFiles");
++              }
++              if (tunable_av_exclude_files) {
++                      if ((ret=regcomp(&av_exclude_files_regex, tunable_av_exclude_files, REG_NOSUB)) != 0)
++                              die("regex compilation failed for AvExcludeFiles");
++              }
++      }
++      return 0;
++}
++
++int av_will_scan(const char *filename) {
++      if (!tunable_av_enable)
++              return 0;
++      if (tunable_av_include_files && (regexec(&av_include_files_regex, filename, 0, 0, 0)!=0))
++              return 0;
++      if (tunable_av_exclude_files && (regexec(&av_exclude_files_regex, filename, 0, 0, 0)==0))
++              return 0;
++      return 1;
++}
++
++int av_init_scanner (struct vsf_session* p_sess) {
++      struct mystr debug_str = INIT_MYSTR;
++
++      if (p_sess->clamd_sock < 0) {
++              
++              /* connect to clamd through local unix socket */
++              if (tunable_av_clamd_socket) {
++                      struct sockaddr_un server_local;
++
++                      vsf_sysutil_memclr((char*)&server_local, sizeof(server_local));
++
++                      server_local.sun_family = AF_UNIX;
++                      vsf_sysutil_strcpy(server_local.sun_path, tunable_av_clamd_socket, sizeof(server_local.sun_path));
++                      if ((p_sess->clamd_sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
++                              str_alloc_text(&debug_str, "av: error opening unix socket");
++                              vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
++                              p_sess->clamd_sock = -2;
++                              return 0;
++                      }
++
++                      if (connect(p_sess->clamd_sock, (struct sockaddr *)&server_local, sizeof(struct sockaddr_un)) < 0) {
++                              str_alloc_text(&debug_str, "av: error connecting to clamd");
++                              vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
++                              p_sess->clamd_sock = -2;
++                              return 0;
++                      }
++
++              } else if (tunable_av_clamd_host) {
++                      struct sockaddr_in server_inet;
++                      struct hostent *he;
++
++                      vsf_sysutil_memclr((char*)&server_inet, sizeof(server_inet));
++
++                      /* Remote Socket */
++                      server_inet.sin_family = AF_INET;
++                      server_inet.sin_port = htons(tunable_av_clamd_port);
++
++                      if ((p_sess->clamd_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
++                              str_alloc_text(&debug_str, "av: error opening inet socket");
++                              vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
++                              p_sess->clamd_sock = -2;
++                              return 0;
++                      }
++
++                      if ((he = gethostbyname(tunable_av_clamd_host)) == 0) {
++                              str_alloc_text(&debug_str, "av: unable to locate clamd host");
++                              vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
++                              vsf_sysutil_close_failok(p_sess->clamd_sock);
++                              p_sess->clamd_sock = -2;
++                              return 0;
++                      }
++
++                      server_inet.sin_addr = *(struct in_addr *) he->h_addr_list[0];
++
++                      if (connect(p_sess->clamd_sock, (struct sockaddr *)&server_inet, sizeof(struct sockaddr_in)) < 0) {
++                              str_alloc_text(&debug_str, "av: error connecting to clamd host");
++                              vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
++                              vsf_sysutil_close_failok(p_sess->clamd_sock);
++                              p_sess->clamd_sock = -2;
++                              return 0;
++                      }
++              }
++
++              if (vsf_sysutil_write(p_sess->clamd_sock, "nIDSESSION\n", 11) <= 0) {
++                      str_alloc_text(&debug_str, "av: error starting clamd session");
++                      vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
++                      vsf_sysutil_close_failok(p_sess->clamd_sock);
++                      p_sess->clamd_sock = -2;
++                      return 0;
++              }
++      }
++
++      return 1;
++}
++
++int av_scan_file(struct vsf_session* p_sess, struct mystr *filename, struct mystr *virname) {
++      struct mystr cwd = INIT_MYSTR;
++      struct mystr clamcmd = INIT_MYSTR;
++      struct mystr response = INIT_MYSTR;
++      char recv_buff[4096];
++      int recv_count;
++      struct str_locate_result locate_res;
++      struct mystr debug_str = INIT_MYSTR;
++      int retry = 0;
++
++init_scan:
++      if (av_init_scanner(p_sess)) {
++
++              str_alloc_text(&clamcmd, "nSCAN ");
++              if (!str_isempty(&p_sess->chroot_str)) {
++                      str_append_str(&clamcmd, &p_sess->chroot_str);
++              }
++              if (str_get_char_at(filename, 0) != '/') {
++                      str_getcwd(&cwd);
++                      str_append_str(&clamcmd, &cwd);
++              }
++              if (str_get_char_at(&clamcmd, str_getlen(&clamcmd) - 1) != '/') { 
++                      str_append_char(&clamcmd, '/');
++              }
++              str_append_str(&clamcmd, filename);
++              str_append_char(&clamcmd, '\n');
++
++//            sprintf(recv_buff, "sockfd: %d", p_sess->clamd_sock);
++//            str_alloc_text(&debug_str, recv_buff);
++//            vsf_log_line(p_sess, kVSFLogEntryDebug, &p_sess->chroot_str);
++//            vsf_log_line(p_sess, kVSFLogEntryDebug, &clamcmd);
++
++              if (vsf_sysutil_write(p_sess->clamd_sock, str_getbuf(&clamcmd), str_getlen(&clamcmd)) <= 0) {
++                      str_alloc_text(&debug_str, "av: failed to scan file");
++                      vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
++                      vsf_sysutil_close_failok(p_sess->clamd_sock);
++                      p_sess->clamd_sock = -2;
++                      return 2;
++              }
++
++              str_free(&clamcmd);
++
++              /* receive and interpret answer */
++              while ((recv_count=vsf_sysutil_read(p_sess->clamd_sock, recv_buff, 4095)) > 0) {
++                      recv_buff[recv_count]=0;
++                      str_append_text(&response, recv_buff);
++                      if (recv_buff[recv_count-1] == '\n')
++                              break;
++              }
++              if (recv_count < 0 || str_getlen(&response) == 0) {
++                      if (!retry) {
++                              retry = 1;
++                              vsf_sysutil_close_failok(p_sess->clamd_sock);
++                              p_sess->clamd_sock = -2;
++                              goto init_scan;
++                      } else {
++                              str_alloc_text(&debug_str, "av: failed to scan file (read failed)");
++                              vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
++                              vsf_sysutil_close(p_sess->clamd_sock);
++                              p_sess->clamd_sock = -2;
++                              return 2;
++                      }
++              }
++              
++              if (str_equal_text(&response, "COMMAND READ TIMED OUT\n")) {
++                      if (!retry) {
++                              retry = 1;
++                              vsf_sysutil_close_failok(p_sess->clamd_sock);
++                              p_sess->clamd_sock = -2;
++                              goto init_scan;
++                      } else {
++                              str_alloc_text(&debug_str, "av: got: ");
++                              str_append_str(&debug_str, &response);
++                              vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
++                              return 2;
++                      }
++              }
++
++
++
++              locate_res = str_locate_text(&response, " FOUND\n");
++              /* virus found */
++              if (locate_res.found) {
++                      str_trunc(&response, locate_res.index);
++                      str_split_text_reverse(&response, virname, ": ");
++                      return 1;
++              }
++              locate_res = str_locate_text(&response, " ERROR\n");
++              if (locate_res.found) {
++                      str_alloc_text(&debug_str, "av: got: ");
++                      str_append_str(&debug_str, &response);
++                      vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
++                      return 2;
++              }
++              return 0;
++      }
++
++      return 2;
++}
++
++
++
++
+diff -Naru vsftpd-2.2.2.orig/clamav.h vsftpd-2.2.2/clamav.h
+--- vsftpd-2.2.2.orig/clamav.h 1970-01-01 01:00:00.000000000 +0100
++++ vsftpd-2.2.2/clamav.h      2010-04-29 19:46:54.435448038 +0200
+@@ -0,0 +1,12 @@
++#ifndef _CLAMAV_H
++#define _CLAMAV_H
++
++#include "str.h"
++#include "session.h"
++
++extern int av_init();
++extern int av_will_scan(const char *filename);
++extern int av_init_scanner (struct vsf_session* p_sess);
++extern int av_scan_file(struct vsf_session* p_sess, struct mystr *filename, struct mystr *virname);
++
++#endif
+diff -Naru vsftpd-2.2.2.orig/main.c vsftpd-2.2.2/main.c
+--- vsftpd-2.2.2.orig/main.c   2009-07-18 07:55:53.000000000 +0200
++++ vsftpd-2.2.2/main.c        2010-04-29 19:46:54.435448038 +0200
+@@ -64,7 +64,9 @@
+     /* Secure connection state */
+     0, 0, 0, 0, 0, INIT_MYSTR, 0, -1, -1,
+     /* Login fails */
+-    0
++    0,
++      /* av */
++      -1, INIT_MYSTR
+   };
+   int config_loaded = 0;
+   int i;
+diff -Naru vsftpd-2.2.2.orig/parseconf.c vsftpd-2.2.2/parseconf.c
+--- vsftpd-2.2.2.orig/parseconf.c      2009-08-07 20:46:40.000000000 +0200
++++ vsftpd-2.2.2/parseconf.c   2010-04-29 19:46:54.435448038 +0200
+@@ -100,6 +100,7 @@
+   { "delete_failed_uploads", &tunable_delete_failed_uploads },
+   { "implicit_ssl", &tunable_implicit_ssl },
+   { "sandbox", &tunable_sandbox },
++  { "av_enable", &tunable_av_enable },
+   { "require_ssl_reuse", &tunable_require_ssl_reuse },
+   { "isolate", &tunable_isolate },
+   { "isolate_network", &tunable_isolate_network },
+@@ -133,6 +134,7 @@
+   { "delay_successful_login", &tunable_delay_successful_login },
+   { "max_login_fails", &tunable_max_login_fails },
+   { "chown_upload_mode", &tunable_chown_upload_mode },
++  { "av_clamd_port", &tunable_av_clamd_port },
+   { 0, 0 }
+ };
+@@ -175,6 +177,10 @@
+   { "dsa_private_key_file", &tunable_dsa_private_key_file },
+   { "ca_certs_file", &tunable_ca_certs_file },
+   { "cmds_denied", &tunable_cmds_denied },
++  { "av_clamd_socket", &tunable_av_clamd_socket },
++  { "av_clamd_host", &tunable_av_clamd_host },
++  { "av_include_files", &tunable_av_include_files },
++  { "av_exclude_files", &tunable_av_exclude_files },
+   { 0, 0 }
+ };
+diff -Naru vsftpd-2.2.2.orig/postlogin.c vsftpd-2.2.2/postlogin.c
+--- vsftpd-2.2.2.orig/postlogin.c      2009-11-07 05:55:12.000000000 +0100
++++ vsftpd-2.2.2/postlogin.c   2010-04-29 19:46:54.438781445 +0200
+@@ -27,6 +27,7 @@
+ #include "ssl.h"
+ #include "vsftpver.h"
+ #include "opts.h"
++#include "clamav.h"
+ /* Private local functions */
+ static void handle_pwd(struct vsf_session* p_sess);
+@@ -972,12 +973,15 @@
+   static struct vsf_sysutil_statbuf* s_p_statbuf;
+   static struct mystr s_filename;
+   struct mystr* p_filename;
++  struct mystr tmp_filename = INIT_MYSTR;
+   struct vsf_transfer_ret trans_ret;
+   int new_file_fd;
++  int av_orig_file_fd = -1;
+   int remote_fd;
+   int success = 0;
+   int created = 0;
+   int do_truncate = 0;
++  int do_av = 0;
+   filesize_t offset = p_sess->restart_pos;
+   p_sess->restart_pos = 0;
+   if (!data_transfer_checks_ok(p_sess))
+@@ -991,6 +995,7 @@
+     get_unique_filename(&s_filename, p_filename);
+     p_filename = &s_filename;
+   }
++
+   vsf_log_start_entry(p_sess, kVSFLogEntryUpload);
+   str_copy(&p_sess->log_str, &p_sess->ftp_arg_str);
+   prepend_path_to_filename(&p_sess->log_str);
+@@ -1022,6 +1027,24 @@
+     return;
+   }
+   created = 1;
++
++  if (av_will_scan(str_getbuf(p_filename))) {
++      do_av = 1;
++      str_copy(&tmp_filename, p_filename);
++      str_append_text(&tmp_filename, ".XXXXXX");
++      av_orig_file_fd = new_file_fd;
++      /* FIXME: various permissions issues... ex. writable file in non-writable directory */
++      new_file_fd = mkstemp(str_getbuf(&tmp_filename));
++      if (vsf_sysutil_retval_is_error(new_file_fd))
++      {
++        vsf_sysutil_close(av_orig_file_fd);
++        vsf_cmdio_write(p_sess, FTP_UPLOADFAIL, "Could not create temp file.");
++        return;
++      }
++      /* mkstemp creates file with 0600 */
++      vsf_sysutil_fchmod(new_file_fd, 0666 &(~vsf_sysutil_get_umask()));
++  }
++
+   vsf_sysutil_fstat(new_file_fd, &s_p_statbuf);
+   if (vsf_sysutil_statbuf_is_regfile(s_p_statbuf))
+   {
+@@ -1047,6 +1070,8 @@
+   if (tunable_lock_upload_files)
+   {
+     vsf_sysutil_lock_file_write(new_file_fd);
++      if (do_av)
++              vsf_sysutil_lock_file_write(av_orig_file_fd);
+   }
+   /* Must truncate the file AFTER locking it! */
+   if (do_truncate)
+@@ -1054,6 +1079,22 @@
+     vsf_sysutil_ftruncate(new_file_fd);
+     vsf_sysutil_lseek_to(new_file_fd, 0);
+   }
++  if (do_av && (is_append || offset != 0)) {
++      char buf[4096];
++      int count;
++
++      /* copy original file */
++      vsf_sysutil_lseek_to(av_orig_file_fd, 0);
++      while ((count=vsf_sysutil_read(av_orig_file_fd, buf, 4096)) > 0) {
++        if (vsf_sysutil_write_loop(new_file_fd, buf, count) < 0) {
++              vsf_cmdio_write(p_sess, FTP_UPLOADFAIL, "Could not copy temp file.");
++              vsf_sysutil_close(new_file_fd);
++              vsf_sysutil_close(av_orig_file_fd);
++              vsf_sysutil_unlink(str_getbuf(&tmp_filename));
++              return;
++        }
++      }
++  }
+   if (!is_append && offset != 0)
+   {
+     /* XXX - warning, allows seek past end of file! Check for seek > size? */
+@@ -1077,6 +1118,7 @@
+   }
+   if (vsf_sysutil_retval_is_error(remote_fd))
+   {
++      vsf_sysutil_unlink(str_getbuf(&tmp_filename));
+     goto port_pasv_cleanup_out;
+   }
+   if (tunable_ascii_upload_enable && p_sess->is_ascii)
+@@ -1097,7 +1139,6 @@
+   if (trans_ret.retval == 0)
+   {
+     success = 1;
+-    vsf_log_do_log(p_sess, 1);
+   }
+   if (trans_ret.retval == -1)
+   {
+@@ -1109,7 +1150,43 @@
+   }
+   else
+   {
+-    vsf_cmdio_write(p_sess, FTP_TRANSFEROK, "Transfer complete.");
++      if (do_av) {
++        struct mystr virname = INIT_MYSTR;
++        struct mystr resp_str = INIT_MYSTR;
++
++        switch (av_scan_file(p_sess, &tmp_filename, &virname)) {
++              case 1:
++                str_alloc_text(&resp_str, "Virus found: ");
++                str_append_str(&resp_str, &virname);
++                vsf_log_line(p_sess, kVSFLogEntryUpload, &resp_str);
++                vsf_cmdio_write(p_sess, FTP_UPLOADFAIL, str_getbuf(&resp_str));
++                str_free(&resp_str);
++
++                str_unlink(&tmp_filename);
++                break;
++              case 2:
++                vsf_cmdio_write(p_sess, FTP_BADSENDFILE, "Failure scanning file.");
++                str_unlink(&tmp_filename);
++                break;
++              default:
++                /* FIXME: race condition */
++                if (vsf_sysutil_rename(str_getbuf(&tmp_filename), str_getbuf(p_filename)) < 0) {
++                      vsf_cmdio_write(p_sess, FTP_BADSENDFILE, "Failure writing to local file .");
++                      str_unlink(&tmp_filename);
++                } 
++                else 
++                {
++                      vsf_log_do_log(p_sess, 1);
++                      vsf_cmdio_write(p_sess, FTP_TRANSFEROK, "File receive OK.");
++                }
++                break;
++        }
++      } 
++      else 
++      {
++        vsf_log_do_log(p_sess, 1);
++        vsf_cmdio_write(p_sess, FTP_TRANSFEROK, "File receive OK.");
++      }
+   }
+   check_abor(p_sess);
+ port_pasv_cleanup_out:
+@@ -1117,9 +1194,15 @@
+   pasv_cleanup(p_sess);
+   if (tunable_delete_failed_uploads && created && !success)
+   {
+-    str_unlink(p_filename);
++      if (do_av) {
++        str_unlink(&tmp_filename);
++      } else {
++        str_unlink(p_filename);
++      }
+   }
+   vsf_sysutil_close(new_file_fd);
++  if (do_av)
++      vsf_sysutil_close(av_orig_file_fd);
+ }
+ static void
+@@ -1898,3 +1981,5 @@
+ {
+   vsf_cmdio_write(p_sess, FTP_LOGINOK, "Already logged in.");
+ }
++
++// vim: sw=2:
+diff -Naru vsftpd-2.2.2.orig/secutil.c vsftpd-2.2.2/secutil.c
+--- vsftpd-2.2.2.orig/secutil.c        2009-05-27 08:20:36.000000000 +0200
++++ vsftpd-2.2.2/secutil.c     2010-04-29 19:46:54.438781445 +0200
+@@ -34,6 +34,7 @@
+     if (p_dir_str == 0 || str_isempty(p_dir_str))
+     {
+       str_alloc_text(&dir_str, vsf_sysutil_user_get_homedir(p_user));
++        str_copy(p_dir_str, &dir_str);
+     }
+     else
+     {
+diff -Naru vsftpd-2.2.2.orig/session.h vsftpd-2.2.2/session.h
+--- vsftpd-2.2.2.orig/session.h        2008-02-12 03:39:38.000000000 +0100
++++ vsftpd-2.2.2/session.h     2010-04-29 19:46:54.438781445 +0200
+@@ -93,6 +93,10 @@
+   int ssl_slave_fd;
+   int ssl_consumer_fd;
+   unsigned int login_fails;
++
++  /* data for av scanner */
++  int clamd_sock;
++  struct mystr chroot_str;
+ };
+ #endif /* VSF_SESSION_H */
+diff -Naru vsftpd-2.2.2.orig/tunables.c vsftpd-2.2.2/tunables.c
+--- vsftpd-2.2.2.orig/tunables.c       2009-07-15 22:08:27.000000000 +0200
++++ vsftpd-2.2.2/tunables.c    2010-04-29 19:48:44.265437093 +0200
+@@ -85,6 +85,8 @@
+ int tunable_isolate;
+ int tunable_isolate_network;
++int tunable_av_enable;
++
+ unsigned int tunable_accept_timeout;
+ unsigned int tunable_connect_timeout;
+ unsigned int tunable_local_umask;
+@@ -105,6 +107,7 @@
+ unsigned int tunable_delay_successful_login;
+ unsigned int tunable_max_login_fails;
+ unsigned int tunable_chown_upload_mode;
++unsigned int tunable_av_clamd_port;
+ const char* tunable_secure_chroot_dir;
+ const char* tunable_ftp_username;
+@@ -139,6 +142,11 @@
+ const char* tunable_dsa_private_key_file;
+ const char* tunable_ca_certs_file;
++const char* tunable_av_clamd_socket;
++const char* tunable_av_clamd_host;
++const char* tunable_av_include_files;
++const char* tunable_av_exclude_files;
++
+ static void install_str_setting(const char* p_value, const char** p_storage);
+ void
+@@ -219,9 +227,10 @@
+   tunable_sandbox = 0;
+   tunable_require_ssl_reuse = 1;
+   tunable_isolate = 1;
+-  tunable_isolate_network = 1;
++  tunable_isolate_network = 0;
+   tunable_ftp_enable = 1;
+   tunable_http_enable = 0;
++  tunable_av_enable = 0;
+   tunable_accept_timeout = 60;
+   tunable_connect_timeout = 60;
+@@ -245,6 +254,7 @@
+   tunable_max_login_fails = 3;
+   /* -rw------- */
+   tunable_chown_upload_mode = 0600;
++  tunable_av_clamd_port = 3310;
+   install_str_setting("/usr/share/empty", &tunable_secure_chroot_dir);
+   install_str_setting("ftp", &tunable_ftp_username);
+@@ -280,6 +290,11 @@
+   install_str_setting(0, &tunable_rsa_private_key_file);
+   install_str_setting(0, &tunable_dsa_private_key_file);
+   install_str_setting(0, &tunable_ca_certs_file);
++
++  install_str_setting(0, &tunable_av_clamd_socket);
++  install_str_setting("127.0.0.1", &tunable_av_clamd_host);
++  install_str_setting(0, &tunable_av_include_files);
++  install_str_setting(0, &tunable_av_exclude_files);
+ }
+ void
+diff -Naru vsftpd-2.2.2.orig/tunables.h vsftpd-2.2.2/tunables.h
+--- vsftpd-2.2.2.orig/tunables.h       2009-07-07 03:37:28.000000000 +0200
++++ vsftpd-2.2.2/tunables.h    2010-04-29 19:46:54.438781445 +0200
+@@ -83,6 +83,7 @@
+ extern int tunable_implicit_ssl;              /* Use implicit SSL protocol */
+ extern int tunable_sandbox;                   /* Deploy ptrace sandbox */
+ extern int tunable_require_ssl_reuse;         /* Require re-used data conn */
++extern int tunable_av_enable;                 /* Scan av incomming files */
+ extern int tunable_isolate;                   /* Use container clone() flags */
+ extern int tunable_isolate_network;           /* Use CLONE_NEWNET */
+@@ -107,6 +108,7 @@
+ extern unsigned int tunable_delay_successful_login;
+ extern unsigned int tunable_max_login_fails;
+ extern unsigned int tunable_chown_upload_mode;
++extern unsigned int tunable_av_clamd_port;
+ /* String defines */
+ extern const char* tunable_secure_chroot_dir;
+@@ -141,6 +143,10 @@
+ extern const char* tunable_dsa_private_key_file;
+ extern const char* tunable_ca_certs_file;
+ extern const char* tunable_cmds_denied;
++extern const char* tunable_av_clamd_socket;
++extern const char* tunable_av_clamd_host;
++extern const char* tunable_av_include_files;
++extern const char* tunable_av_exclude_files;
+ #endif /* VSF_TUNABLES_H */
+diff -Naru vsftpd-2.2.2.orig/twoprocess.c vsftpd-2.2.2/twoprocess.c
+--- vsftpd-2.2.2.orig/twoprocess.c     2009-07-18 07:56:44.000000000 +0200
++++ vsftpd-2.2.2/twoprocess.c  2010-04-29 19:46:54.438781445 +0200
+@@ -428,6 +428,13 @@
+                         p_user_str, p_orig_user_str);
+     vsf_secutil_change_credentials(p_user_str, &userdir_str, &chroot_str,
+                                    0, secutil_option);
++
++      if (do_chroot) {
++              str_copy(&p_sess->chroot_str, &userdir_str);
++      } else {
++              str_empty(&p_sess->chroot_str);
++      }
++
+     if (!str_isempty(&chdir_str))
+     {
+       (void) str_chdir(&chdir_str);
+diff -Naru vsftpd-2.2.2.orig/vsftpd.conf.5 vsftpd-2.2.2/vsftpd.conf.5
+--- vsftpd-2.2.2.orig/vsftpd.conf.5    2009-10-19 04:46:30.000000000 +0200
++++ vsftpd-2.2.2/vsftpd.conf.5 2010-04-29 19:46:54.438781445 +0200
+@@ -105,6 +105,11 @@
+ Default: NO
+ .TP
++.B av_enable
++If enabled, all uploaded files are scanned with clamav (through clamd).
++
++Default: NO
++.TP
+ .B background
+ When enabled, and vsftpd is started in "listen" mode, vsftpd will background
+ the listener process. i.e. control will immediately be returned to the shell
+@@ -643,6 +648,11 @@
+ Default: 077
+ .TP
++.B av_clamd_port
++Port number where clamd listen on.
++
++Default: 3310
++.TP
+ .B chown_upload_mode
+ The file mode to force for chown()ed anonymous uploads. (Added in v2.0.6).
+@@ -758,6 +768,18 @@
+ Default: (none)
+ .TP
++.B av_clamd_host
++IP where clamd listen. It must be on the same host (or have access to same
++filesystem).
++
++Default: 127.0.0.1
++.TP
++.B av_clamd_socket
++UNIX socket of clamd. Warning: When using chroot you should use TCP instead of
++UNIX socket.
++
++Default: (none)
++.TP
+ .B banned_email_file
+ This option is the name of a file containing a list of anonymous e-mail
+ passwords which are not permitted. This file is consulted if the option
diff --git a/vsftpd-findlibs-egrep.patch b/vsftpd-findlibs-egrep.patch
new file mode 100644 (file)
index 0000000..6167406
--- /dev/null
@@ -0,0 +1,11 @@
+--- vsftpd-3.0.2/vsf_findlibs.sh.orig  2014-04-11 12:18:03.231578533 +0200
++++ vsftpd-3.0.2/vsf_findlibs.sh       2014-04-11 12:19:03.988273239 +0200
+@@ -2,7 +2,7 @@
+ # Cheesy hacky location of additional link libraries.
+ locate_library() { [ ! "$1*" = "`echo $1*`" ]; }
+-find_func() { egrep $1 $2 >/dev/null; }
++find_func() { egrep -qa $1 $2; }
+ if find_func hosts_access tcpwrap.o; then
+   echo "-lwrap";
diff --git a/vsftpd-ftpusers b/vsftpd-ftpusers
new file mode 100644 (file)
index 0000000..856df2f
--- /dev/null
@@ -0,0 +1,14 @@
+root
+bin
+daemon
+adm
+lp
+sync
+shutdown
+halt
+mail
+news
+uucp
+operator
+games
+nobody
diff --git a/vsftpd-switch_sha256_to_sha1.patch b/vsftpd-switch_sha256_to_sha1.patch
new file mode 100644 (file)
index 0000000..c9dddfa
--- /dev/null
@@ -0,0 +1,11 @@
+--- ./ssl.c.org        2009-10-19 04:34:08.000000000 +0200
++++ ./ssl.c    2010-12-28 17:33:27.730241842 +0100
+@@ -608,7 +608,7 @@ ssl_cert_digest(SSL* p_ssl, struct vsf_s
+   str_reserve(p_str, EVP_MAX_MD_SIZE);
+   str_empty(p_str);
+   str_rpad(p_str, EVP_MAX_MD_SIZE);
+-  if (!X509_digest(p_cert, EVP_sha256(), (unsigned char*) str_getbuf(p_str),
++  if (!X509_digest(p_cert, EVP_sha1(), (unsigned char*) str_getbuf(p_str),
+                    &num_bytes))
+   {
+     die("X509_digest failed");
diff --git a/vsftpd-use-evp_sha1.patch b/vsftpd-use-evp_sha1.patch
new file mode 100644 (file)
index 0000000..b76cb31
--- /dev/null
@@ -0,0 +1,11 @@
+--- vsftpd-2.1.0/ssl.c~        2009-01-09 21:47:05.000000000 +0100
++++ vsftpd-2.1.0/ssl.c 2010-06-03 11:28:01.145540532 +0200
+@@ -593,7 +593,7 @@
+   str_reserve(p_str, EVP_MAX_MD_SIZE);
+   str_empty(p_str);
+   str_rpad(p_str, EVP_MAX_MD_SIZE);
+-  if (!X509_digest(p_cert, EVP_sha256(), (unsigned char*) str_getbuf(p_str),
++  if (!X509_digest(p_cert, EVP_sha1(), (unsigned char*) str_getbuf(p_str),
+                    &num_bytes))
+   {
+     die("X509_digest failed");
diff --git a/vsftpd.inetd b/vsftpd.inetd
new file mode 100644 (file)
index 0000000..5a4b76b
--- /dev/null
@@ -0,0 +1,10 @@
+SERVICE_NAME=ftp
+SOCK_TYPE=stream
+PROTOCOL=tcp
+PORT=21
+FLAGS=nowait
+USER=root
+SERVER=tcpd
+DAEMON=/usr/sbin/vsftpd
+DAEMONARGS="-olisten=NO"
+NICE=10
diff --git a/vsftpd.init b/vsftpd.init
new file mode 100644 (file)
index 0000000..811b710
--- /dev/null
@@ -0,0 +1,74 @@
+#!/bin/sh
+#
+# vsftpd       vsftp server
+#
+# chkconfig:   345 85 15
+# description: VSFTPD is a Very Secure FTP Daemon
+#
+
+# Source function library
+. /etc/rc.d/init.d/functions
+
+# Get network config
+. /etc/sysconfig/network
+
+# Check that networking is up.
+if is_yes "${NETWORKING}"; then
+       if [ ! -f /var/lock/subsys/network -a "$1" != stop -a "$1" != status ]; then
+               msg_network_down vsftpd
+               exit 1
+       fi
+else
+       exit 0
+fi
+
+start() {
+       # Check if the service is already running?
+       if [ ! -f /var/lock/subsys/vsftpd ]; then
+               # Check if we have 'Listen=yes' in config
+               if ! egrep -q '^(listen|listen_ipv6)=([Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|1)' /etc/vsftpd.conf; then
+                       echo "error: Missing 'listen=yes' or 'listen_ipv6=yes' directive in /etc/vsftpd.conf!"
+                       exit 1
+               fi;
+               # try to load capability module
+               _modprobe capability
+               msg_starting vsftpd
+               daemon --fork /usr/sbin/vsftpd 
+               RETVAL=$?
+               [ $RETVAL -eq 0 ] && touch /var/lock/subsys/vsftpd
+       else
+               msg_already_running vsftpd
+       fi
+}
+
+stop() {
+       # Stop daemons.
+       if [ -f /var/lock/subsys/vsftpd ]; then
+               msg_stopping vsftpd
+               killproc vsftpd
+               rm -f /var/lock/subsys/vsftpd > /dev/null 2>&1
+       else
+               msg_not_running vsftpd
+       fi
+}
+
+RETVAL=0
+# See how we were called.
+case "$1" in
+  start)
+       start
+       ;;
+  stop)
+       stop
+       ;;
+  restart|force-reload)
+       stop
+       start
+       ;;
+  *)
+       msg_usage "$0 {start|stop|restart|force-reload}"
+       exit 3
+       ;;
+esac
+
+exit $RETVAL
diff --git a/vsftpd.pamd b/vsftpd.pamd
new file mode 100644 (file)
index 0000000..3aeb5ca
--- /dev/null
@@ -0,0 +1,6 @@
+#%PAM-1.0
+auth           required        pam_listfile.so item=user sense=deny file=/etc/ftpd/ftpusers onerr=succeed
+auth           include         system-auth
+account                required        pam_nologin.so
+account                include         system-auth
+session                include         system-auth
diff --git a/vsftpd.spec b/vsftpd.spec
new file mode 100644 (file)
index 0000000..c07f354
--- /dev/null
@@ -0,0 +1,194 @@
+# TODO:
+# - default config does not work with inetd configuration
+#
+# Conditional build:
+%bcond_with    clamav  # ClamAV scanning support
+
+%define                _ftpdir /home/services/ftp
+Summary:       vsftpd - Very Secure FTP Daemon
+Summary(pl.UTF-8):     Bardzo Bezpieczny Demon FTP
+Summary(pt_BR.UTF-8):  vsftpd - Daemon FTP Muito Seguro
+Name:          vsftpd
+Version:       3.0.3
+Release:       1
+License:       GPL v2
+Group:         Daemons
+Source0:       https://security.appspot.com/downloads/%{name}-%{version}.tar.gz
+# Source0-md5: da119d084bd3f98664636ea05b5bb398
+Source1:       %{name}.inetd
+Source2:       %{name}.pamd
+Source3:       %{name}-ftpusers
+Source4:       ftpusers.tar.bz2
+# Source4-md5: 76c80b6ec9f4d079a1e27316edddbe16
+Source5:       %{name}.init
+Patch0:                %{name}-builddefs.patch
+Patch1:                %{name}-amd64-findlibs.patch
+Patch2:                %{name}-clamav.patch
+Patch3:                %{name}-switch_sha256_to_sha1.patch
+Patch4:                %{name}-findlibs-egrep.patch
+URL:           https://security.appspot.com/vsftpd.html
+BuildRequires: libcap-devel
+BuildRequires: libwrap-devel
+%if "%{pld_release}" == "ac"
+BuildRequires: openssl-devel >= 0.9.7d
+%else
+BuildRequires: openssl-devel >= 0.9.8
+%endif
+BuildRequires: rpmbuild(macros) >= 1.268
+Requires:      %{name}-init = %{version}-%{release}
+Requires:      filesystem >= 3.0-11
+Requires:      pam >= 0.77.3
+Provides:      ftpserver
+Conflicts:     man-pages < 1.51
+BuildRoot:     %{tmpdir}/%{name}-%{version}-root-%(id -u -n)
+
+%define        specflags       -fpie -pipe -Wextra -Werror
+
+%description
+A Very Secure FTP Daemon - written from scratch - by Chris "One Man
+Security Audit Team" Evans.
+
+%description -l pl.UTF-8
+Bardzo Bezpieczny Demon FTP - napisany od zera przez Chrisa "One Man
+Security Audit Team" Evansa.
+
+%description -l pt_BR.UTF-8
+A Very Secure FTP Daemon (vsftpd) - escrito do zero - por Chris "One
+Man Security Audit Team" Evans.
+
+%package inetd
+Summary:       vsftpd - Very Secure FTP Daemon
+Summary(pl.UTF-8):     Bardzo Bezpieczny Demon FTP
+Summary(pt_BR.UTF-8):  vsftpd - Daemon FTP Muito Seguro
+Group:         Networking/Daemons
+Requires:      %{name} = %{version}-%{release}
+Requires:      rc-inetd
+Provides:      %{name}-init = %{version}-%{release}
+Obsoletes:     vsftpd-standalone
+Conflicts:     %{name} <= 2.0.3-1
+
+%description inetd
+This package allows to start vsftpd as inetd service.
+
+%description inetd -l pl.UTF-8
+Ten pakiet pozwala na wystartowanie vsftpd jako usÅ‚ugi inetd.
+
+%package standalone
+Summary:       vsftpd - Very Secure FTP Daemon
+Summary(pl.UTF-8):     Bardzo Bezpieczny Demon FTP
+Summary(pt_BR.UTF-8):  vsftpd - Daemon FTP Muito Seguro
+Group:         Networking/Daemons
+Requires(post,preun):  /sbin/chkconfig
+Requires:      %{name} = %{version}-%{release}
+Requires:      rc-scripts
+Provides:      %{name}-init = %{version}-%{release}
+Obsoletes:     vsftpd-inetd
+Conflicts:     %{name} <= 2.0.3-1
+
+%description standalone
+This package allows to start vsftpd as standalone daemon.
+
+%description standalone -l pl.UTF-8
+Ten pakiet pozwala na wystartowanie vsftpd jako samodzielnego demona.
+
+%prep
+%setup -q
+%patch0 -p1
+%patch1 -p1
+%if %{with clamav}
+%patch2 -p1
+%endif
+%if "%{pld_release}" == "ac"
+%patch3 -p1
+%endif
+%patch4 -p1
+
+%build
+%{__make} \
+       CC="%{__cc}" \
+       CFLAGS="%{rpmcflags}" \
+       LIBS="-lwrap -lpam -lcap -lssl -lcrypto" \
+       LINK="%{rpmldflags}"
+
+%install
+rm -rf $RPM_BUILD_ROOT
+install -d $RPM_BUILD_ROOT{%{_sbindir},%{_mandir}/man{5,8}} \
+       $RPM_BUILD_ROOT/etc/{pam.d,sysconfig/rc-inetd,logrotate.d,ftpd,rc.d/init.d} \
+       $RPM_BUILD_ROOT{%{_ftpdir}/pub/incoming,/var/log}
+
+install -p vsftpd $RPM_BUILD_ROOT%{_sbindir}/vsftpd
+cp -p vsftpd.conf $RPM_BUILD_ROOT%{_sysconfdir}/vsftpd.conf
+cp -p vsftpd.conf.5 $RPM_BUILD_ROOT%{_mandir}/man5/vsftpd.conf.5
+cp -p vsftpd.8 $RPM_BUILD_ROOT%{_mandir}/man8/vsftpd.8
+cp -p RedHat/vsftpd.log $RPM_BUILD_ROOT/etc/logrotate.d/vsftpd
+
+install -p %{SOURCE1} $RPM_BUILD_ROOT/etc/sysconfig/rc-inetd/vsftpd
+cp -p %{SOURCE2} $RPM_BUILD_ROOT/etc/pam.d/ftp
+cp -p %{SOURCE3} $RPM_BUILD_ROOT%{_sysconfdir}/ftpd/ftpusers
+install -p %{SOURCE5} $RPM_BUILD_ROOT/etc/rc.d/init.d/vsftpd
+
+> $RPM_BUILD_ROOT/var/log/vsftpd.log
+
+bzip2 -dc %{SOURCE4} | tar xf - -C $RPM_BUILD_ROOT%{_mandir}
+%{__rm} $RPM_BUILD_ROOT%{_mandir}/ftpusers-path.diff
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post
+touch /var/log/vsftpd.log
+chmod 640 /var/log/vsftpd.log
+
+%post inetd
+%service -q rc-inetd reload
+
+%postun inetd
+if [ "$1" = "0" ]; then
+       %service -q rc-inetd reload
+fi
+
+%post standalone
+/sbin/chkconfig --add %{name}
+%service vsftpd restart "vsftpd server"
+
+%preun standalone
+if [ "$1" = "0" ]; then
+       %service vsftpd stop
+       /sbin/chkconfig --del %{name}
+fi
+
+%triggerin standalone -- glibc
+# restart vsftpd if glibc is upgraded or downgraded
+if [ "$2" != 1 ]; then
+       %service -q vsftpd restart
+fi
+
+%files
+%defattr(644,root,root,755)
+%doc AUDIT BENCHMARKS BUGS Changelog FAQ README README.ssl REWARD SIZE SPEED TODO TUNING EXAMPLE SECURITY
+%attr(755,root,root) %{_sbindir}/vsftpd
+%dir %attr(750,root,ftp) %dir %{_sysconfdir}/ftpd
+%attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/vsftpd.conf
+%attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/ftpd/ftpusers
+%attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) /etc/pam.d/ftp
+%attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) /etc/logrotate.d/vsftpd
+%attr(640,root,root) %ghost /var/log/vsftpd.log
+%{_mandir}/man5/vsftpd.conf.5*
+%{_mandir}/man8/vsftpd.8*
+%{_mandir}/man5/ftpusers.5*
+%lang(ja) %{_mandir}/ja/man5/ftpusers*
+%lang(pl) %{_mandir}/pl/man5/ftpusers*
+%lang(pt_BR) %{_mandir}/pt_BR/man5/ftpusers*
+%lang(ru) %{_mandir}/ru/man5/ftpusers*
+%dir %{_ftpdir}
+%dir %{_ftpdir}/pub
+# it's safe - by default anon_upload_enable=NO, anon_world_readable_only=YES
+%attr(775,root,ftp) %dir %{_ftpdir}/pub/incoming
+
+%files inetd
+%defattr(644,root,root,755)
+%attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) /etc/sysconfig/rc-inetd/vsftpd
+
+%files standalone
+%defattr(644,root,root,755)
+%attr(754,root,root) /etc/rc.d/init.d/vsftpd