From f07ce4dfd71a33dbf886759883aad9d265229694 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 10 Oct 2023 21:28:10 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20Sync=202023-10-10=2021:28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vsftpd-alt/Makefile | 113 ++++++++ vsftpd-alt/files/vsftpd-uci.init | 14 + vsftpd-alt/files/vsftpd.conf | 30 +++ vsftpd-alt/files/vsftpd.init | 13 + vsftpd-alt/files/vsftpd.uci | 50 ++++ vsftpd-alt/files/vsftpd_prepare | 253 ++++++++++++++++++ vsftpd-alt/files/vsftpd_wrapper | 49 ++++ vsftpd-alt/patches/001-destdir.patch | 47 ++++ vsftpd-alt/patches/002-find_libs.patch | 13 + vsftpd-alt/patches/003-chroot.patch | 11 + .../patches/004-disable-capabilities.patch | 12 + vsftpd-alt/patches/005-disable-pam.patch | 11 + .../patches/006-musl-compatibility.patch | 13 + vsftpd-alt/patches/007-CVE-2015-1419.patch | 98 +++++++ .../patches/100-add-uci-auth-support.patch | 127 +++++++++ .../101-enable-chroot-on-writable-dir.patch | 14 + .../patches/102-keep-local-user-rights.patch | 11 + 17 files changed, 879 insertions(+) create mode 100644 vsftpd-alt/Makefile create mode 100644 vsftpd-alt/files/vsftpd-uci.init create mode 100644 vsftpd-alt/files/vsftpd.conf create mode 100644 vsftpd-alt/files/vsftpd.init create mode 100644 vsftpd-alt/files/vsftpd.uci create mode 100755 vsftpd-alt/files/vsftpd_prepare create mode 100755 vsftpd-alt/files/vsftpd_wrapper create mode 100644 vsftpd-alt/patches/001-destdir.patch create mode 100644 vsftpd-alt/patches/002-find_libs.patch create mode 100644 vsftpd-alt/patches/003-chroot.patch create mode 100644 vsftpd-alt/patches/004-disable-capabilities.patch create mode 100644 vsftpd-alt/patches/005-disable-pam.patch create mode 100644 vsftpd-alt/patches/006-musl-compatibility.patch create mode 100644 vsftpd-alt/patches/007-CVE-2015-1419.patch create mode 100644 vsftpd-alt/patches/100-add-uci-auth-support.patch create mode 100644 vsftpd-alt/patches/101-enable-chroot-on-writable-dir.patch create mode 100644 vsftpd-alt/patches/102-keep-local-user-rights.patch diff --git a/vsftpd-alt/Makefile b/vsftpd-alt/Makefile new file mode 100644 index 00000000..d94026d8 --- /dev/null +++ b/vsftpd-alt/Makefile @@ -0,0 +1,113 @@ +# +# Copyright (C) 2006-2014 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=vsftpd-alt +PKG_VERSION:=3.0.3 +PKG_RELEASE:=5 + +PKG_SOURCE:=vsftpd-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://security.appspot.com/downloads/ +PKG_MD5SUM:=da119d084bd3f98664636ea05b5bb398 +PKG_LICENSE:=GPLv2 + +BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) +PKG_BUILD_DIR:=$(BUILD_DIR)/vsftpd-$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk + +define Package/vsftpd-alt/Default + SUBMENU:=File Transfer + SECTION:=net + CATEGORY:=Network + TITLE:=A fast and secure FTP server (with aio support) + URL:=http://vsftpd.beasts.org/ + MAINTAINER:=Cezary Jackiewicz + DEPENDS=+libuci + #+PACKAGE_libpam:libpam +endef + +define Package/vsftpd-alt/conffiles +/etc/vsftpd.conf +endef + +#EXTRA_LDFLAGS:= -lcrypt -lcrypto -lssl + +define Package/vsftpd-alt/config +config VSFTPD_USE_UCI_SCRIPTS + bool "Uses UCI scripts" + depends on PACKAGE_vsftpd-alt + default y +#config VSFTPD_ENABLE_AIO +# bool "Enable async I/O (Currently Buggy)" +# depends on PACKAGE_vsftpd-alt +# default n +endef + +ifneq ($(CONFIG_USE_MUSL),) + NLSSTRING:=-lcrypt +else + NLSSTRING:=-lcrypt -lnsl +endif + +TARGET_CFLAGS += -D_GNU_SOURCE -include fcntl.h + +#ifdef CONFIG_PACKAGE_libpam +# EXTRA_LDFLAGS += -lpam +#endif + +#ifeq ($(CONFIG_VSFTPD_ENABLE_AIO),y) +#define Package/vsftpd-alt +#$(call Package/vsftpd-alt/Default) +# DEPENDS=+PACKAGE_libpam:libpam +libopenssl +libuci +libaio +#endef +# EXTRA_LDFLAGS += -laio +# EXTRA_CFLAGS += -DVSFTPD_ASYNC_IO +#else +define Package/vsftpd-alt +$(call Package/vsftpd-alt/Default) +endef +#endif + + +define Build/Compile + $(SED) 's/-lcrypt -lnsl/$(NLSSTRING)/' $(PKG_BUILD_DIR)/Makefile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CC="$(TARGET_CC)" \ + CFLAGS="$(TARGET_CFLAGS)" \ + LDFLAGS="$(TARGET_LDFLAGS)" \ + vsftpd +endef + +ifeq ($(CONFIG_VSFTPD_USE_UCI_SCRIPTS),y) +define Package/vsftpd-alt/install +$(call Package/vsftpd-alt/install/default, $(1)) + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DIR) $(1)/etc/config +ifdef CONFIG_PACKAGE_libpam + $(INSTALL_DIR) $(1)/etc/pam.d +endif + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/vsftpd $(1)/usr/sbin + $(INSTALL_BIN) ./files/vsftpd-uci.init $(1)/etc/init.d/vsftpd + $(INSTALL_BIN) ./files/vsftpd.uci $(1)/etc/config/vsftpd + $(INSTALL_BIN) ./files/vsftpd_wrapper $(1)/usr/sbin + $(INSTALL_BIN) ./files/vsftpd_prepare $(1)/usr/sbin +endef +else +define Package/vsftpd-alt/install +$(call Package/vsftpd-alt/install/default, $(1)) + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_CONF) ./files/vsftpd.conf $(1)/etc/vsftpd.conf + $(INSTALL_BIN) ./files/vsftpd.init $(1)/etc/init.d/vsftpd + $(INSTALL_BIN) $(PKG_BUILD_DIR)/vsftpd $(1)/usr/sbin +endef +endif + +$(eval $(call BuildPackage,vsftpd-alt)) diff --git a/vsftpd-alt/files/vsftpd-uci.init b/vsftpd-alt/files/vsftpd-uci.init new file mode 100644 index 00000000..a5af8b79 --- /dev/null +++ b/vsftpd-alt/files/vsftpd-uci.init @@ -0,0 +1,14 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006-2011 OpenWrt.org + +START=50 + +start() { + /usr/sbin/vsftpd_prepare + service_start /usr/sbin/vsftpd_wrapper ipv4 + service_start /usr/sbin/vsftpd_wrapper ipv6 +} + +stop() { + service_stop /usr/sbin/vsftpd +} diff --git a/vsftpd-alt/files/vsftpd.conf b/vsftpd-alt/files/vsftpd.conf new file mode 100644 index 00000000..7d46506e --- /dev/null +++ b/vsftpd-alt/files/vsftpd.conf @@ -0,0 +1,30 @@ +background=YES +listen=YES +anonymous_enable=NO +local_enable=YES +write_enable=YES +local_umask=022 +check_shell=NO +#dirmessage_enable=YES +#ftpd_banner=Welcome to blah FTP service. +session_support=NO +#syslog_enable=YES +#userlist_enable=YES +#userlist_deny=NO +#userlist_file=/etc/vsftpd.users +#xferlog_enable=YES +#xferlog_file=/var/log/vsftpd.log +#xferlog_std_format=YES +### +### TLS/SSL options +### example key generation: openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/config/vsftpd_privkey.pem -out /etc/config/vsftpd_cert.pem -subj /C="DE"/ST="Saxony"/L="Leipzig"/CN="OpenWrt" +#ssl_enable=YES +#allow_anon_ssl=NO +#force_local_data_ssl=NO +#force_local_logins_ssl=NO +#ssl_tlsv1=YES +#ssl_sslv2=NO +#ssl_sslv3=NO +#rsa_cert_file=/etc/config/vsftpd_cert.pem +#rsa_private_key_file=/etc/config/vsftpd_privkey.pem + diff --git a/vsftpd-alt/files/vsftpd.init b/vsftpd-alt/files/vsftpd.init new file mode 100644 index 00000000..ad3e23da --- /dev/null +++ b/vsftpd-alt/files/vsftpd.init @@ -0,0 +1,13 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006-2011 OpenWrt.org + +START=50 + +start() { + mkdir -m 0755 -p /var/run/vsftpd + service_start /usr/sbin/vsftpd +} + +stop() { + service_stop /usr/sbin/vsftpd +} diff --git a/vsftpd-alt/files/vsftpd.uci b/vsftpd-alt/files/vsftpd.uci new file mode 100644 index 00000000..e856c16d --- /dev/null +++ b/vsftpd-alt/files/vsftpd.uci @@ -0,0 +1,50 @@ + +config listen 'listen' + option enable4 '1' + option ipv4 '0.0.0.0' + option enable6 '0' + option ipv6 '::1' + option port '21' + option dataport '20' + +config local 'local' + option enabled '1' + +config global 'global' + option write '1' + option download '1' + option dotfile '0' + option umask '022' + option dirlist '1' + option dirmsgfile '.message' + +config connection 'connection' + option portmode '1' + option pasvmode '1' + option ascii 'both' + option idletimeout '1800' + option conntimeout '120' + option dataconntimeout '120' + option maxclient '0' + option maxperip '0' + option maxrate '0' + option maxretry '3' + +config anonymous 'anonymous' + option enabled '0' + option username 'ftp' + option root '/home/ftp' + option umask '022' + option writemkdir '0' + option upload '0' + option others '0' + option maxrate '0' + +config log 'log' + option syslog '0' + option xreflog '1' + option file '/var/log/vsftpd.log' + +config vuser 'vuser' + option enabled '0' + option username 'ftp' diff --git a/vsftpd-alt/files/vsftpd_prepare b/vsftpd-alt/files/vsftpd_prepare new file mode 100755 index 00000000..62267196 --- /dev/null +++ b/vsftpd-alt/files/vsftpd_prepare @@ -0,0 +1,253 @@ +#!/bin/sh +# Copyright (C) 2005-2016 Weijie Gao + +. $IPKG_INSTROOT/lib/functions.sh + +output_field() +{ + local UCI_SECTION=$1 + local KEY=$2 + local INIFIELD=$3 + local DEFVALUE=$4 + local value + + if [ -z "$INIFIELD" ]; then INIFIELD=$KEY; fi + + config_get value "$UCI_SECTION" "$KEY" + if [ -z "$value" ]; then value=$DEFVALUE; fi + + echo "$INIFIELD=$value" >> $CONF +} + +output_bool() +{ + local UCI_SECTION=$1 + local KEY=$2 + local INIFIELD=$3 + local DEFVALUE=$4 + local value + + if [ -z "$INIFIELD" ]; then INIFIELD=$KEY; fi + + config_get value "$UCI_SECTION" "$KEY" + if [ -z "$value" ]; then value=$DEFVALUE; fi + if [ x"$value" != x0 ] && [ x"$value" != x1 ]; then value=0; fi + + if [ "$value" == 0 ]; then + value=NO + else + value=YES + fi + + echo "$INIFIELD=$value" >> $CONF +} + +output_const() +{ + local INIFIELD=$1 + local value=$2 + + echo "$INIFIELD=$value" >> $CONF +} + +get_value() +{ + local UCI_SECTION=$1 + local KEY=$2 + local value + + config_get value "$UCI_SECTION" "$KEY" + + echo $value +} + +vusers_iterate() +{ + local config=$1 + local name + local password + local owner + local home + local _umask + local maxrate + local write_enable + local upload_enable + local mkdir_enable + local others_enable + + config_get name "$config" username + config_get password "$config" password + config_get home "$config" home + config_get _umask "$config" "umask" + config_get maxrate "$config" maxrate + config_get write_enable "$config" writemkdir + config_get upload_enable "$config" upload + config_get others_enable "$config" others + + config_get owner "vuser" username + + rm -f $VUSER_CONF_DIR/$name + touch $VUSER_CONF_DIR/$name + + if [ -z $home ]; then home=$CHROOT_DIR; fi + + echo "local_root=$home" >> $VUSER_CONF_DIR/$name + + if [ x$write_enable = x1 ]; then write_enable=YES; else write_enable=NO; fi + if [ x$upload_enable = x1 ]; then upload_enable=YES; else upload_enable=NO; fi + if [ x$others_enable = x1 ]; then others_enable=YES; else others_enable=NO; fi + if [ -z $_umask ]; then _umask=022; fi + if [ -z $maxrate ]; then maxrate=0; fi + + echo "anon_world_readable_only=NO" >> $VUSER_CONF_DIR/$name + echo "anon_mkdir_write_enable=$write_enable" >> $VUSER_CONF_DIR/$name + echo "write_enable=$write_enable" >> $VUSER_CONF_DIR/$name + echo "anon_upload_enable=$upload_enable" >> $VUSER_CONF_DIR/$name + echo "anon_other_write_enable=$others_enable" >> $VUSER_CONF_DIR/$name + echo "anon_umask=$_umask" >> $VUSER_CONF_DIR/$name + echo "anon_max_rate=$maxrate" >> $VUSER_CONF_DIR/$name + + if ! [ -d "$home" ]; then + mkdir -p $home + chown $owner:$owner $home + chmod -R a+w $home + fi +} + +VAR=/var/run/vsftpd +CONF=$VAR/vsftpd.conf +VUSER_DB=$VAR/vusers +VUSER_CONF_DIR=$VAR/users +CHROOT_DIR=$VAR/empty + +rm -f $CONF +rm -rf $VUSER_CONF_DIR $CHROOT_DIR + +mkdir -m 0755 -p $VAR +mkdir -p $VUSER_CONF_DIR +mkdir -p $CHROOT_DIR + +config_load vsftpd + +# listen +output_const "background" YES +output_field listen port "listen_port" 21 +output_field listen dataport "ftp_data_port" 20 + +# global +output_bool global 'write' "write_enable" 1 +output_bool global download "download_enable" 1 +output_bool global dirlist "dirlist_enable" 1 +output_bool global lsrecurse "ls_recurse_enable" +output_bool global dotfile "force_dot_files" +output_field global 'umask' "local_umask" 022 + +ftpd_banner=`get_value global ftpd_banner` +if ! [ -z $ftpd_banner ]; then + output_const "ftpd_banner" $ftpd_banner +fi + +output_bool global dirmessage "dirmessage_enable" +output_field global dirmsgfile "message_file" ".message" + +# connection +output_bool connection portmode "port_enable" 1 +output_bool connection pasvmode "pasv_enable" 1 + +ascii_download_enable=NO +ascii_upload_enable=NO +case `get_value connection ascii` in +download) + ascii_download_enable=YES +;; +upload) + ascii_upload_enable=YES +;; +both) + ascii_download_enable=YES + ascii_upload_enable=YES +esac +output_const "ascii_download_enable" $ascii_download_enable +output_const "ascii_upload_enable" $ascii_upload_enable + +output_field connection idletimeout "idle_session_timeout" 1800 +output_field connection conntimeout "connect_timeout" 120 +output_field connection dataconntimeout "data_connection_timeout" 120 +output_field connection maxclient "max_clients" 0 +output_field connection maxperip "max_per_ip" 0 +output_field connection maxrate "local_max_rate" 0 + +max_login_fails=`get_value connection maxretry` +if [ -z $max_login_fails ] || [ $max_login_fails -lt 1 ]; then max_login_fails=3; fi +output_const "max_login_fails" $max_login_fails + +# anonymous +ftp_username=`get_value anonymous ftp_username` +if [ -z $ftp_username ]; then ftp_username="ftp"; fi +output_const "ftp_username" $ftp_username + +mkdir -m 0755 -p /home/$ftp_username +chown $ftp_username:$ftp_username /home/$ftp_username + +output_const "anon_world_readable_only" NO + +anon_enable=`get_value anonymous enabled` +if [ x$anon_enable = x1 ]; then + anon_root=`get_value anonymous root` + if [ -z $anon_root ]; then anon_root="/home/ftp"; fi + + output_const "anonymous_enable" YES + output_const "no_anon_password" YES + output_const "anon_root" $anon_root + output_field anonymous 'umask' "anon_umask" 022 + output_field anonymous maxrate "anon_max_rate" 0 + output_bool anonymous writemkdir "anon_mkdir_write_enable" 0 + output_bool anonymous upload "anon_upload_enable" 0 + output_bool anonymous others "anon_other_write_enable" 0 + + mkdir -p $anon_root + chown -R $ftp_username:$ftp_username $anon_root +else + output_const "anonymous_enable" NO +fi + +# log +output_bool log syslog "syslog_enable" 0 +output_bool log xreflog "xferlog_enable" 0 +output_field log 'file' "vsftpd_log_file" 0 + +# users +vuser_enabled=0 +if [ x`get_value vuser enabled` = x1 ]; then + vuser_enabled=1 + + output_const "guest_enable" YES + output_field vuser username "guest_username" ftp + + output_const "uci_config_name" vsftpd + output_const "user_config_dir" "/var/run/vsftpd/users" + + config_foreach vusers_iterate user +fi + +# local user +output_const "allow_writeable_chroot" YES +output_const "secure_chroot_dir" $CHROOT_DIR + +local_root=$(get_value 'local' root) +if ! [ -z $local_root ]; then + output_const "local_root" $local_root +fi + +local_enable=`get_value 'local' enabled` +if [ x$local_enable = x1 ]; then + output_const "local_enable" YES +else + if [ $vuser_enabled = 1 ]; then + output_const "local_enable" YES + else + output_const "local_enable" NO + fi +fi + +exit 0 diff --git a/vsftpd-alt/files/vsftpd_wrapper b/vsftpd-alt/files/vsftpd_wrapper new file mode 100755 index 00000000..73a2ef4e --- /dev/null +++ b/vsftpd-alt/files/vsftpd_wrapper @@ -0,0 +1,49 @@ +#!/bin/sh +# Copyright (C) 2005-2016 Weijie Gao + +. $IPKG_INSTROOT/lib/functions.sh + +VAR=/var/run/vsftpd +CONF=$VAR/vsftpd.conf +listen_addr= +enabled= +param="" +listen4= +listen6= +protocol=$1 + +config_load vsftpd + +if ! [ -f $CONF ]; then + echo "/usr/bin/vsftpd_prepare must be executed before this script" + exit 1 +fi + +case $protocol in +ipv6) + config_get enabled listen enable6 + + if [ x$enabled != x1 ]; then exit 0; fi + + config_get listen_addr listen ipv6 + param="6" + listen4="-olisten=NO" + listen6="-olisten_ipv6=YES" + + if [ -z $listen_addr ]; then listen_addr="::"; fi +;; +*) + config_get enabled listen enable4 + + if [ x$enabled != x1 ]; then exit 0; fi + + config_get listen_addr listen ipv4 + listen4="-olisten=YES" + listen6="-olisten_ipv6=NO" + + if [ -z $listen_addr ]; then listen_addr="0.0.0.0"; fi +esac + +exec /usr/sbin/vsftpd "-olisten_address${param}=${listen_addr}" ${listen4} ${listen6} $CONF + +exit 1 diff --git a/vsftpd-alt/patches/001-destdir.patch b/vsftpd-alt/patches/001-destdir.patch new file mode 100644 index 00000000..b0274ac8 --- /dev/null +++ b/vsftpd-alt/patches/001-destdir.patch @@ -0,0 +1,47 @@ +--- a/Makefile ++++ b/Makefile +@@ -22,6 +22,8 @@ OBJS = main.o utility.o prelogin.o ftpcm + seccompsandbox.o + + ++DESTDIR = ++ + .c.o: + $(CC) -c $*.c $(CFLAGS) $(IFLAGS) + +@@ -29,21 +31,20 @@ vsftpd: $(OBJS) + $(CC) -o vsftpd $(OBJS) $(LINK) $(LDFLAGS) $(LIBS) + + install: +- if [ -x /usr/local/sbin ]; then \ +- $(INSTALL) -m 755 vsftpd /usr/local/sbin/vsftpd; \ +- else \ +- $(INSTALL) -m 755 vsftpd /usr/sbin/vsftpd; fi +- if [ -x /usr/local/man ]; then \ +- $(INSTALL) -m 644 vsftpd.8 /usr/local/man/man8/vsftpd.8; \ +- $(INSTALL) -m 644 vsftpd.conf.5 /usr/local/man/man5/vsftpd.conf.5; \ +- elif [ -x /usr/share/man ]; then \ +- $(INSTALL) -m 644 vsftpd.8 /usr/share/man/man8/vsftpd.8; \ +- $(INSTALL) -m 644 vsftpd.conf.5 /usr/share/man/man5/vsftpd.conf.5; \ +- else \ +- $(INSTALL) -m 644 vsftpd.8 /usr/man/man8/vsftpd.8; \ +- $(INSTALL) -m 644 vsftpd.conf.5 /usr/man/man5/vsftpd.conf.5; fi +- if [ -x /etc/xinetd.d ]; then \ +- $(INSTALL) -m 644 xinetd.d/vsftpd /etc/xinetd.d/vsftpd; fi ++ mkdir -p $(DESTDIR)/usr/sbin ++ $(INSTALL) -m 755 vsftpd $(DESTDIR)/usr/sbin/ ++ mkdir -p $(DESTDIR)/usr/share/man/man8 ++ $(INSTALL) -m 644 vsftpd.8 $(DESTDIR)/usr/share/man/man8/ ++ mkdir -p $(DESTDIR)/usr/share/man/man5 ++ $(INSTALL) -m 644 vsftpd.conf.5 $(DESTDIR)/usr/share/man/man5/ ++ mkdir -p $(DESTDIR)/etc/xinetd.d ++ $(INSTALL) -m 644 xinetd.d/vsftpd $(DESTDIR)/etc/xinetd.d/ ++ ++uninstall: ++ rm -f $(DESTDIR)/usr/sbin/vsftpd ++ rm -f $(DESTDIR)/usr/share/man/man8/vsftpd.8 ++ rm -f $(DESTDIR)/usr/share/man/man5/vsftpd.conf.5 ++ rm -f $(DESTDIR)/etc/xinetd.d/vsftpd + + clean: + rm -f *.o *.swp vsftpd diff --git a/vsftpd-alt/patches/002-find_libs.patch b/vsftpd-alt/patches/002-find_libs.patch new file mode 100644 index 00000000..4e95248c --- /dev/null +++ b/vsftpd-alt/patches/002-find_libs.patch @@ -0,0 +1,13 @@ +--- a/Makefile ++++ b/Makefile +@@ -8,8 +8,8 @@ CFLAGS = -O2 -fPIE -fstack-protector --p + -D_FORTIFY_SOURCE=2 \ + #-pedantic -Wconversion + +-LIBS = `./vsf_findlibs.sh` +-LINK = -Wl,-s ++LIBS = -lcrypt -lnsl -luci ++LINK = + LDFLAGS = -fPIE -pie -Wl,-z,relro -Wl,-z,now + + OBJS = main.o utility.o prelogin.o ftpcmdio.o postlogin.o privsock.o \ diff --git a/vsftpd-alt/patches/003-chroot.patch b/vsftpd-alt/patches/003-chroot.patch new file mode 100644 index 00000000..8965da41 --- /dev/null +++ b/vsftpd-alt/patches/003-chroot.patch @@ -0,0 +1,11 @@ +--- a/tunables.c ++++ b/tunables.c +@@ -254,7 +254,7 @@ tunables_load_defaults() + /* -rw------- */ + tunable_chown_upload_mode = 0600; + +- install_str_setting("/usr/share/empty", &tunable_secure_chroot_dir); ++ install_str_setting("/var/run/vsftpd", &tunable_secure_chroot_dir); + install_str_setting("ftp", &tunable_ftp_username); + install_str_setting("root", &tunable_chown_username); + install_str_setting("/var/log/xferlog", &tunable_xferlog_file); diff --git a/vsftpd-alt/patches/004-disable-capabilities.patch b/vsftpd-alt/patches/004-disable-capabilities.patch new file mode 100644 index 00000000..7aa6330b --- /dev/null +++ b/vsftpd-alt/patches/004-disable-capabilities.patch @@ -0,0 +1,12 @@ +--- a/sysdeputil.c ++++ b/sysdeputil.c +@@ -165,6 +165,9 @@ + #endif + /* END config */ + ++#undef VSF_SYSDEP_HAVE_CAPABILITIES ++#undef VSF_SYSDEP_HAVE_LIBCAP ++ + /* PAM support - we include our own dummy version if the system lacks this */ + #include + diff --git a/vsftpd-alt/patches/005-disable-pam.patch b/vsftpd-alt/patches/005-disable-pam.patch new file mode 100644 index 00000000..ebb72447 --- /dev/null +++ b/vsftpd-alt/patches/005-disable-pam.patch @@ -0,0 +1,11 @@ +--- a/builddefs.h ++++ b/builddefs.h +@@ -2,7 +2,7 @@ + #define VSF_BUILDDEFS_H + + #undef VSF_BUILD_TCPWRAPPERS +-#define VSF_BUILD_PAM ++#undef VSF_BUILD_PAM + #undef VSF_BUILD_SSL + + #endif /* VSF_BUILDDEFS_H */ diff --git a/vsftpd-alt/patches/006-musl-compatibility.patch b/vsftpd-alt/patches/006-musl-compatibility.patch new file mode 100644 index 00000000..9eefec79 --- /dev/null +++ b/vsftpd-alt/patches/006-musl-compatibility.patch @@ -0,0 +1,13 @@ +--- a/sysdeputil.c ++++ b/sysdeputil.c +@@ -58,7 +58,9 @@ + #define VSF_SYSDEP_HAVE_SHADOW + #define VSF_SYSDEP_HAVE_USERSHELL + #define VSF_SYSDEP_HAVE_LIBCAP +-#define VSF_SYSDEP_HAVE_UTMPX ++#if defined(__GLIBC__) || defined(__UCLIBC__) ++ #define VSF_SYSDEP_HAVE_UTMPX ++#endif + + #define __USE_GNU + #include diff --git a/vsftpd-alt/patches/007-CVE-2015-1419.patch b/vsftpd-alt/patches/007-CVE-2015-1419.patch new file mode 100644 index 00000000..173027a1 --- /dev/null +++ b/vsftpd-alt/patches/007-CVE-2015-1419.patch @@ -0,0 +1,98 @@ +Description: CVE-2015-1419: config option deny_file is not handled correctly +Author: Marcus Meissner +Origin: https://bugzilla.novell.com/show_bug.cgi?id=CVE-2015-1419 +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=776922 +Last-Update: 2015-02-24 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/ls.c ++++ b/ls.c +@@ -7,6 +7,7 @@ + * Would you believe, code to handle directory listing. + */ + ++#include + #include "ls.h" + #include "access.h" + #include "defs.h" +@@ -243,11 +244,42 @@ vsf_filename_passes_filter(const struct + struct mystr temp_str = INIT_MYSTR; + struct mystr brace_list_str = INIT_MYSTR; + struct mystr new_filter_str = INIT_MYSTR; ++ struct mystr normalize_filename_str = INIT_MYSTR; ++ const char *normname; ++ const char *path; + int ret = 0; + char last_token = 0; + int must_match_at_current_pos = 1; ++ + str_copy(&filter_remain_str, p_filter_str); +- str_copy(&name_remain_str, p_filename_str); ++ ++ /* normalize filepath */ ++ path = str_strdup(p_filename_str); ++ normname = realpath(path, NULL); ++ if (normname == NULL) ++ goto out; ++ str_alloc_text(&normalize_filename_str, normname); ++ ++ if (!str_isempty (&filter_remain_str) && !str_isempty(&normalize_filename_str)) { ++ if (str_get_char_at(p_filter_str, 0) == '/') { ++ if (str_get_char_at(&normalize_filename_str, 0) != '/') { ++ str_getcwd (&name_remain_str); ++ ++ if (str_getlen(&name_remain_str) > 1) /* cwd != root dir */ ++ str_append_char (&name_remain_str, '/'); ++ ++ str_append_str (&name_remain_str, &normalize_filename_str); ++ } ++ else ++ str_copy (&name_remain_str, &normalize_filename_str); ++ } else { ++ if (str_get_char_at(p_filter_str, 0) != '{') ++ str_basename (&name_remain_str, &normalize_filename_str); ++ else ++ str_copy (&name_remain_str, &normalize_filename_str); ++ } ++ } else ++ str_copy(&name_remain_str, &normalize_filename_str); + + while (!str_isempty(&filter_remain_str) && *iters < VSFTP_MATCHITERS_MAX) + { +@@ -360,6 +392,9 @@ vsf_filename_passes_filter(const struct + ret = 0; + } + out: ++ free(normname); ++ free(path); ++ str_free(&normalize_filename_str); + str_free(&filter_remain_str); + str_free(&name_remain_str); + str_free(&temp_str); +--- a/str.c ++++ b/str.c +@@ -711,3 +711,14 @@ str_replace_unprintable(struct mystr* p_ + } + } + ++void ++str_basename (struct mystr* d_str, const struct mystr* path) ++{ ++ static struct mystr tmp; ++ ++ str_copy (&tmp, path); ++ str_split_char_reverse(&tmp, d_str, '/'); ++ ++ if (str_isempty(d_str)) ++ str_copy (d_str, path); ++} +--- a/str.h ++++ b/str.h +@@ -100,6 +100,7 @@ void str_replace_unprintable(struct myst + int str_atoi(const struct mystr* p_str); + filesize_t str_a_to_filesize_t(const struct mystr* p_str); + unsigned int str_octal_to_uint(const struct mystr* p_str); ++void str_basename (struct mystr* d_str, const struct mystr* path); + + /* PURPOSE: Extract a line of text (delimited by \n or EOF) from a string + * buffer, starting at character position 'p_pos'. The extracted line will diff --git a/vsftpd-alt/patches/100-add-uci-auth-support.patch b/vsftpd-alt/patches/100-add-uci-auth-support.patch new file mode 100644 index 00000000..3b805645 --- /dev/null +++ b/vsftpd-alt/patches/100-add-uci-auth-support.patch @@ -0,0 +1,127 @@ +--- a/parseconf.c ++++ b/parseconf.c +@@ -178,6 +178,7 @@ + { "rsa_private_key_file", &tunable_rsa_private_key_file }, + { "dsa_private_key_file", &tunable_dsa_private_key_file }, + { "ca_certs_file", &tunable_ca_certs_file }, ++ { "uci_config_name", &tunable_uci_config_name }, + { "cmds_denied", &tunable_cmds_denied }, + { 0, 0 } + }; +--- a/sysdeputil.c ++++ b/sysdeputil.c +@@ -175,6 +175,8 @@ + #include + #include + #include ++/* Include uci headers */ ++#include + #endif + + /* Prefer libcap based capabilities over raw syscall capabilities */ +@@ -237,14 +239,24 @@ + void vsf_remove_uwtmp(void); + + #ifndef VSF_SYSDEP_HAVE_PAM ++static int ++vsf_sysdep_check_auth_uci(struct mystr* p_user_str, ++ const struct mystr* p_pass_str); ++ + int + vsf_sysdep_check_auth(struct mystr* p_user_str, + const struct mystr* p_pass_str, + const struct mystr* p_remote_host) + { + const char* p_crypted; +- const struct passwd* p_pwd = getpwnam(str_getbuf(p_user_str)); ++ const struct passwd* p_pwd; + (void) p_remote_host; ++ ++ /* Try UCI first */ ++ if (vsf_sysdep_check_auth_uci(p_user_str, p_pass_str)) ++ return 1; ++ ++ p_pwd = getpwnam(str_getbuf(p_user_str)); + if (p_pwd == NULL) + { + return 0; +@@ -300,6 +312,51 @@ + return 0; + } + ++static int ++vsf_sysdep_check_auth_uci(struct mystr* p_user_str, ++ const struct mystr* p_pass_str) ++{ ++ struct uci_context *uctx; ++ struct uci_package *pkg = NULL; ++ struct uci_element *e = NULL; ++ struct uci_section *s; ++ const char *user, *passwd; ++ int ret = 0; ++ ++ if (!tunable_uci_config_name) ++ return 0; ++ ++ uctx = uci_alloc_context(); ++ if (!uctx) ++ return 0; ++ ++ if (uci_load(uctx, tunable_uci_config_name, &pkg) != UCI_OK) ++ goto cleanup; ++ ++ uci_foreach_element(&pkg->sections, e) ++ { ++ s = uci_to_section(e); ++ if (!(user = uci_lookup_option_string(uctx, s, "username"))) ++ continue; ++ if (vsf_sysutil_strcmp(user, str_getbuf(p_user_str))) ++ continue; ++ if (!(passwd = uci_lookup_option_string(uctx, s, "password"))) ++ continue; ++ if (!vsf_sysutil_strcmp(passwd, str_getbuf(p_pass_str))) ++ { ++ ret = 1; ++ break; ++ } ++ } ++ ++cleanup: ++ if (pkg) ++ uci_unload(uctx, pkg); ++ uci_free_context(uctx); ++ ++ return ret; ++} ++ + #else /* VSF_SYSDEP_HAVE_PAM */ + + #if (defined(__sun) || defined(__hpux)) && \ +--- a/tunables.c ++++ b/tunables.c +@@ -142,6 +142,7 @@ + const char* tunable_rsa_private_key_file; + const char* tunable_dsa_private_key_file; + const char* tunable_ca_certs_file; ++const char* tunable_uci_config_name; + + static void install_str_setting(const char* p_value, const char** p_storage); + +@@ -288,6 +289,7 @@ + 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_uci_config_name); + } + + void +--- a/tunables.h ++++ b/tunables.h +@@ -144,6 +144,7 @@ + extern const char* tunable_rsa_private_key_file; + extern const char* tunable_dsa_private_key_file; + extern const char* tunable_ca_certs_file; ++extern const char* tunable_uci_config_name; + extern const char* tunable_cmds_denied; + + #endif /* VSF_TUNABLES_H */ diff --git a/vsftpd-alt/patches/101-enable-chroot-on-writable-dir.patch b/vsftpd-alt/patches/101-enable-chroot-on-writable-dir.patch new file mode 100644 index 00000000..c7a6b05f --- /dev/null +++ b/vsftpd-alt/patches/101-enable-chroot-on-writable-dir.patch @@ -0,0 +1,14 @@ +--- a/secutil.c ++++ b/secutil.c +@@ -135,10 +135,12 @@ + if ((options & VSF_SECUTIL_OPTION_CHROOT) && + !(options & VSF_SECUTIL_OPTION_ALLOW_WRITEABLE_ROOT)) + { ++ /* + if (vsf_sysutil_write_access("/")) + { + die("vsftpd: refusing to run with writable root inside chroot()"); + } ++ */ + } + } diff --git a/vsftpd-alt/patches/102-keep-local-user-rights.patch b/vsftpd-alt/patches/102-keep-local-user-rights.patch new file mode 100644 index 00000000..f5ee25d7 --- /dev/null +++ b/vsftpd-alt/patches/102-keep-local-user-rights.patch @@ -0,0 +1,11 @@ +--- a/twoprocess.c ++++ b/twoprocess.c +@@ -426,7 +426,7 @@ + */ + vsf_set_die_if_parent_dies(); + priv_sock_set_child_context(p_sess); +- if (tunable_guest_enable && !anon) ++ if (tunable_guest_enable && !anon && !str_getpwnam(p_user_str)) + { + p_sess->is_guest = 1; + /* Remap to the guest user */