re-add vsftpd and luci

This commit is contained in:
coolsnowwolf 2018-10-08 17:24:51 +08:00
parent 6315864b01
commit e2edfce7a8
26 changed files with 1494 additions and 0 deletions

View File

@ -0,0 +1,17 @@
# Copyright (C) 2016 Openwrt.org
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI support for VSFTPD
LUCI_DEPENDS:=+vsftpd-alt
LUCI_PKGARCH:=all
PKG_VERSION:=1.0
PKG_RELEASE:=2
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -0,0 +1,47 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2016 Weijie Gao <hackpascal@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
require("luci.sys")
module("luci.controller.vsftpd", package.seeall)
function index()
if not nixio.fs.access("/etc/config/vsftpd") then
return
end
entry({"admin", "nas"}, firstchild(), "NAS", 44).dependent = false
entry({"admin", "nas", "vsftpd"},
alias("admin", "nas", "vsftpd", "general"),
_("FTP Server"))
entry({"admin", "nas", "vsftpd", "general"},
cbi("vsftpd/general"),
_("General Settings"), 10).leaf = true
entry({"admin", "nas", "vsftpd", "users"},
cbi("vsftpd/users"),
_("Virtual Users"), 20).leaf = true
entry({"admin", "nas", "vsftpd", "anonymous"},
cbi("vsftpd/anonymous"),
_("Anonymous User"), 30).leaf = true
entry({"admin", "nas", "vsftpd", "log"},
cbi("vsftpd/log"),
_("Log Settings"), 40).leaf = true
entry({"admin", "nas", "vsftpd", "item"},
cbi("vsftpd/item"), nil).leaf = true
end

View File

@ -0,0 +1,44 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2016 Weijie Gao <hackpascal@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
m = Map("vsftpd", translate("FTP Server - Anonymous Settings"))
sa = m:section(NamedSection, "anonymous", "anonymous", translate("Anonymous Settings"))
o = sa:option(Flag, "enabled", translate("Enabled"))
o.default = false
o = sa:option(Value, "username", translate("Username"), translate("An actual local user to handle anonymous user"))
o.default = "ftp"
o = sa:option(Value, "root", translate("Root directory"))
o.default = "/home/ftp"
o = sa:option(Value, "umask", translate("File mode umask"))
o.default = "022"
o = sa:option(Value, "maxrate", translate("Max transmit rate"), translate("0 means no limitation"))
o.default = "0"
o = sa:option(Flag, "writemkdir", translate("Enable write/mkdir"))
o.default = false
o = sa:option(Flag, "upload", translate("Enable upload"))
o.default = false
o = sa:option(Flag, "others", translate("Enable other rights"), translate("Include rename, deletion ..."))
o.default = false
return m

View File

@ -0,0 +1,114 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2016 Weijie Gao <hackpascal@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
m = Map("vsftpd", translate("FTP Server - General Settings"))
sl = m:section(NamedSection, "listen", "listen", translate("Listening Settings"))
o = sl:option(Flag, "enable4", translate("Enable IPv4"))
o.rmempty = false
o.default = true
o = sl:option(Value, "ipv4", translate("IPv4 Address"))
o.datatype = "ip4addr"
o.default = "0.0.0.0"
o = sl:option(Flag, "enable6", translate("Enable IPv6"))
o.rmempty = false
o = sl:option(Value, "ipv6", translate("IPv6 Address"))
o.datatype = "ip6addr"
o.default = "::"
o = sl:option(Value, "port", translate("Listen Port"))
o.datatype = "uinteger"
o.default = "21"
o = sl:option(Value, "dataport", translate("Data Port"))
o.datatype = "uinteger"
o.default = "20"
sg = m:section(NamedSection, "global", "global", translate("Global Settings"))
o = sg:option(Flag, "write", translate("Enable write"), translate("When disabled, all write request will give permission denied."));
o.default = true
o = sg:option(Flag, "download", translate("Enable download"), translate("When disabled, all download request will give permission denied."));
o.default = true
o = sg:option(Flag, "dirlist", translate("Enable directory list"), translate("When disabled, list commands will give permission denied."))
o.default = true
o = sg:option(Flag, "lsrecurse", translate("Allow directory recursely list"))
o = sg:option(Flag, "dotfile", translate("Show dot files"), translate(". and .. are excluded."));
o.default = true
o = sg:option(Value, "umask", translate("File mode umask"), translate("Uploaded file mode will be 666 - &lt;umask&gt;; directory mode will be 777 - &lt;umask&gt;."))
o.default = "022"
o = sg:option(Value, "banner", translate("FTP Banner"))
o = sg:option(Flag, "dirmessage", translate("Enable directory message"), translate("A message will be displayed when entering a directory."))
o = sg:option(Value, "dirmsgfile", translate("Directory message filename"))
o.default = ".message"
sl = m:section(NamedSection, "local", "local", translate("Local Users"))
o = sl:option(Flag, "enabled", translate("Enable local user"))
o.rmempty = false
o = sl:option(Value, "root", translate("Root directory"), translate("Leave empty will use user's home directory"))
o.default = ""
sc = m:section(NamedSection, "connection", "connection", translate("Connection Settings"))
o = sc:option(Flag, "portmode", translate("Enable PORT mode"))
o = sc:option(Flag, "pasvmode", translate("Enable PASV mode"))
o = sc:option(ListValue, "ascii", translate("ASCII mode"))
o:value("disabled", translate("Disabled"))
o:value("download", translate("Download only"))
o:value("upload", translate("Upload only"))
o:value("both", translate("Both download and upload"))
o.default = "both"
o = sc:option(Value, "idletimeout", translate("Idle session timeout"), translate("in seconds"))
o.datatype = "uinteger"
o.default = "1800"
o = sc:option(Value, "conntimeout", translate("Connection timeout"), translate("in seconds"))
o.datatype = "uinteger"
o.default = "120"
o = sc:option(Value, "dataconntimeout", translate("Data connection timeout"), translate("in seconds"))
o.datatype = "uinteger"
o.default = "120"
o = sc:option(Value, "maxclient", translate("Max clients"), translate("0 means no limitation"))
o.datatype = "uinteger"
o.default = "0"
o = sc:option(Value, "maxperip", translate("Max clients per IP"), translate("0 means no limitation"))
o.datatype = "uinteger"
o.default = "0"
o = sc:option(Value, "maxrate", translate("Max transmit rate"), translate("in KB/s, 0 means no limitation"))
o.datatype = "uinteger"
o.default = "0"
o = sc:option(Value, "maxretry", translate("Max login fail count"), translate("Can not be zero, default is 3"))
o.datatype = "uinteger"
o.default = "3"
return m

View File

@ -0,0 +1,70 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2016 Weijie Gao <hackpascal@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local sid = arg[1]
local utl = require "luci.util"
m = Map("vsftpd", translate("FTP Server - Virtual User &lt;new&gt;"))
m.redirect = luci.dispatcher.build_url("admin/nas/vsftpd/users")
if m.uci:get("vsftpd", sid) ~= "user" then
luci.http.redirect(m.redirect)
return
end
m.uci:foreach("vsftpd", "user",
function(s)
if s['.name'] == sid and s.username then
m.title = translatef("FTP Server - Virtual User %q", s.username)
return false
end
end)
s = m:section(NamedSection, sid, "settings", translate("User Settings"))
s.addremove = false
o = s:option(Value, "username", translate("Username"))
o.rmempty = false
function o.validate(self, value)
if value == "" then
return nil, translate("Username cannot be empty")
end
return value
end
o = s:option(Value, "password", translate("Password"))
o.password = true
o = s:option(Value, "home", translate("Home directory"))
o.default = "/home/ftp"
o = s:option(Value, "umask", translate("File mode umask"))
o.default = "022"
o = s:option(Value, "maxrate", translate("Max transmit rate"), translate("0 means no limitation"))
o.default = "0"
o = s:option(Flag, "writemkdir", translate("Enable write/mkdir"))
o.default = false
o = s:option(Flag, "upload", translate("Enable upload"))
o.default = false
o = s:option(Flag, "others", translate("Enable other rights"), translate("Include rename, deletion ..."))
o.default = false
return m

View File

@ -0,0 +1,29 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2016 Weijie Gao <hackpascal@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
m = Map("vsftpd", translate("FTP Server - Log Settings"))
sl = m:section(NamedSection, "log", "log", translate("Log Settings"))
o = sl:option(Flag, "syslog", translate("Enable syslog"))
o.default = false
o = sl:option(Flag, "xreflog", translate("Enable file log"))
o.default = true
o = sl:option(Value, "file", translate("Log file"))
o.default = "/var/log/vsftpd.log"
return m

View File

@ -0,0 +1,54 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2016 Weijie Gao <hackpascal@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
m = Map("vsftpd", translate("FTP Server - Virtual User Settings"))
sv = m:section(NamedSection, "vuser", "vuser", translate("Settings"))
o = sv:option(Flag, "enabled", translate("Enabled"))
o.default = false
o = sv:option(Value, "username", translate("Username"), translate("An actual local user to handle virtual users"))
o.default = "ftp"
s = m:section(TypedSection, "user", translate("User lists"))
s.template = "cbi/tblsection"
s.extedit = luci.dispatcher.build_url("admin/nas/vsftpd/item/%s")
s.addremove = true
s.anonymous = true
function s.create(...)
local id = TypedSection.create(...)
luci.http.redirect(s.extedit % id)
end
function s.remove(self, section)
return TypedSection.remove(self, section)
end
o = s:option(DummyValue, "username", translate("Username"))
function o.cfgvalue(...)
local v = Value.cfgvalue(...) or ("<%s>" % translate("Unknown"))
return v
end
o.rmempty = false
o = s:option(DummyValue, "home", translate("Home directory"))
function o.cfgvalue(...)
local v = Value.cfgvalue(...) or ("/home/ftp")
return v
end
o.rmempty = false
return m

View File

@ -0,0 +1,229 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-02-17 18:00+0800\n"\
"Last-Translator: Weijie Gao <hackpascal@gmail.com>\n"
"Language-Team: \n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Pootle 2.0.6\n"
msgid "NAS"
msgstr "网络存储"
msgid ". and .. are excluded."
msgstr ". 和 .. 将被忽略。"
msgid "0 means no limitation"
msgstr "0 表明不限制"
msgid "A message will be displayed when entering a directory."
msgstr "在进入一个新目录时将显示的消息"
msgid "ASCII mode"
msgstr "ASCII 模式"
msgid "Allow directory recursely list"
msgstr "允许递归列目录"
msgid "An actual local user to handle anonymous user"
msgstr "承载匿名用户的本地用户"
msgid "An actual local user to handle virtual users"
msgstr "承载虚拟用户的本地用户"
msgid "Anonymous Settings"
msgstr "匿名用户设置"
msgid "Anonymous User"
msgstr "匿名用户"
msgid "Both download and upload"
msgstr "下载和上传"
msgid "Can not be zero, default is 3"
msgstr "不能为 0默认为 3"
msgid "Connection Settings"
msgstr "连接设置"
msgid "Connection timeout"
msgstr "连接超时"
msgid "Data Port"
msgstr "数据端口"
msgid "Data connection timeout"
msgstr "数据连接超时"
msgid "Directory message filename"
msgstr "目录消息文件名"
msgid "Download only"
msgstr "仅下载"
msgid "Enable IPv4"
msgstr "启用 IPv4"
msgid "Enable IPv6"
msgstr "启用 IPv6"
msgid "Enable PASV mode"
msgstr "启用 PASV 模式"
msgid "Enable PORT mode"
msgstr "启用 PORT 模式"
msgid "Enable directory list"
msgstr "允许列目录"
msgid "Enable directory message"
msgstr "启用目录消息"
msgid "Enable download"
msgstr "允许下载"
msgid "Enable file log"
msgstr "启用文件日志"
msgid "Enable local user"
msgstr "启用本地用户"
msgid "Enable other rights"
msgstr "允许其它权限"
msgid "Enable syslog"
msgstr "启用系统日志"
msgid "Enable upload"
msgstr "允许上传"
msgid "Enable write"
msgstr "允许写"
msgid "Enable write/mkdir"
msgstr "允许写/创建目录"
msgid "FTP Banner"
msgstr "FTP 欢迎提示"
msgid "FTP Server"
msgstr "FTP 服务器"
msgid "FTP Server - Anonymous Settings"
msgstr "FTP 服务器 - 匿名用户设置"
msgid "FTP Server - General Settings"
msgstr "FTP 服务器 - 常规设置"
msgid "FTP Server - Log Settings"
msgstr "FTP 服务器 - 日志设置"
msgid "FTP Server - Virtual User %q"
msgstr "FTP 服务器 - 虚拟用户 %q"
msgid "FTP Server - Virtual User &lt;new&gt;"
msgstr "FTP 服务器 - 虚拟用户 &lt;新用户&gt;"
msgid "FTP Server - Virtual User Settings"
msgstr "FTP 服务器 - 虚拟用户设置"
msgid "File mode umask"
msgstr "文件权限掩码"
msgid "General Settings"
msgstr "常规设置"
msgid "Global Settings"
msgstr "全局设置"
msgid "Home directory"
msgstr "主目录"
msgid "IPv4 Address"
msgstr "IPv4 地址"
msgid "IPv6 Address"
msgstr "IPv6 地址"
msgid "Idle session timeout"
msgstr "空闲回话超时"
msgid "Include rename, deletion ..."
msgstr "包括重命名、删除 ..."
msgid "Leave empty will use user's home directory"
msgstr "留空将使用用户主目录"
msgid "Listen Port"
msgstr "监听端口"
msgid "Listening Settings"
msgstr "监听设置"
msgid "Local Users"
msgstr "本地用户"
msgid "Log Settings"
msgstr "日志设置"
msgid "Log file"
msgstr "日志文件"
msgid "Max clients"
msgstr "最大连接数"
msgid "Max clients per IP"
msgstr "同一 IP 的最大连接数"
msgid "Max login fail count"
msgstr "最大登录尝试数"
msgid "Max transmit rate"
msgstr "最大传输速率"
msgid "Root directory"
msgstr "根目录"
msgid "Settings"
msgstr "设置"
msgid "Show dot files"
msgstr "显示以点开头的文件 (隐藏文件)"
msgid "Upload only"
msgstr "仅上传"
msgid "Uploaded file mode will be 666 - &lt;umask&gt;; directory mode will be 777 - &lt;umask&gt;."
msgstr "上传的文件权限将被设置为 666 - &lt;掩码&gt;;目录权限将被设置为 777 - &lt;掩码&gt;。"
msgid "User Settings"
msgstr "用户设置"
msgid "User lists"
msgstr "用户列表"
msgid "Username cannot be empty"
msgstr "用户名不能为空"
msgid "When disabled, all download request will give permission denied."
msgstr "如果禁止,所有的下载请求都将被拒绝。"
msgid "When disabled, all write request will give permission denied."
msgstr "如果禁止,所有的写类型请求都将被拒绝。"
msgid "When disabled, list commands will give permission denied."
msgstr "如果禁止,列目录命令将被拒绝。"
msgid "Virtual Users"
msgstr "虚拟用户"
msgid "in seconds"
msgstr "单位为秒"
msgid "in KB/s, 0 means no limitation"
msgstr "单位为 KB/s0 表明不限制"

View File

@ -0,0 +1,11 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete ucitrack.@vsftpd[-1]
add ucitrack vsftpd
set ucitrack.@vsftpd[-1].init=vsftpd
commit ucitrack
EOF
rm -f /tmp/luci-vsftpd
exit 0

View File

@ -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 <cezary@eko.one.pl>
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))

View File

@ -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
}

View File

@ -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

View File

@ -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
}

View File

@ -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'

View File

@ -0,0 +1,253 @@
#!/bin/sh
# Copyright (C) 2005-2016 Weijie Gao <hackpascal@gmail.com>
. $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

View File

@ -0,0 +1,49 @@
#!/bin/sh
# Copyright (C) 2005-2016 Weijie Gao <hackpascal@gmail.com>
. $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

View File

@ -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

View File

@ -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 \

View File

@ -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);

View File

@ -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 <security/pam_appl.h>

View File

@ -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 */

View File

@ -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 <utmpx.h>

View File

@ -0,0 +1,98 @@
Description: CVE-2015-1419: config option deny_file is not handled correctly
Author: Marcus Meissner <meissner@suse.com>
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 <stdlib.h>
#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

View File

@ -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 <pwd.h>
#include <unistd.h>
#include <crypt.h>
+/* Include uci headers */
+#include <uci.h>
#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 */

View File

@ -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()");
}
+ */
}
}

View File

@ -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 */