!7 update proftpd to 1.3.7a

From: @eaglegai
Reviewed-by: @small_leek
Signed-off-by: @small_leek
This commit is contained in:
openeuler-ci-bot 2021-06-01 19:37:55 +08:00 committed by Gitee
commit 6ca024b4b3
38 changed files with 955 additions and 2152 deletions

View File

@ -1,78 +0,0 @@
From 08ba2f630c8eebd023ae68d8e2abd1e7170468af Mon Sep 17 00:00:00 2001
From: TJ Saunders <tj@castaglia.org>
Date: Sun, 14 May 2017 14:09:23 -0700
Subject: [PATCH] Issue #501: Avoid a spurious "Address already in use" error
on startup because we are listening on a local socket twice.
---
modules/mod_ctrls.c | 22 +++++++---------------
1 file changed, 7 insertions(+), 15 deletions(-)
diff --git a/modules/mod_ctrls.c b/modules/mod_ctrls.c
index 25ea723..8efd8b4 100644
--- a/modules/mod_ctrls.c
+++ b/modules/mod_ctrls.c
@@ -2,8 +2,7 @@
* ProFTPD: mod_ctrls -- a module implementing the ftpdctl local socket
* server, as well as several utility functions for other Controls
* modules
- *
- * Copyright (c) 2000-2016 TJ Saunders
+ * Copyright (c) 2000-2017 TJ Saunders
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -81,8 +80,6 @@ static ctrls_acl_t ctrls_sock_acl;
static unsigned char ctrls_engine = TRUE;
-#define CTRLS_LISTEN_FL_REMOVE_SOCKET 0x0001
-
/* Necessary prototypes */
static int ctrls_setblock(int sockfd);
static int ctrls_setnonblock(int sockfd);
@@ -437,7 +434,7 @@ static int ctrls_cls_write(void) {
}
/* Create a listening local socket */
-static int ctrls_listen(const char *sock_file, int flags) {
+static int ctrls_listen(const char *sock_file) {
int sockfd = -1, len = 0;
struct sockaddr_un sock;
#if !defined(SO_PEERCRED) && !defined(HAVE_GETPEEREID) && \
@@ -497,12 +494,10 @@ static int ctrls_listen(const char *sock_file, int flags) {
return -1;
}
- if (flags & CTRLS_LISTEN_FL_REMOVE_SOCKET) {
- /* Make sure the path to which we want to bind this socket doesn't already
- * exist.
- */
- (void) unlink(sock_file);
- }
+ /* Make sure the path to which we want to bind this socket doesn't already
+ * exist.
+ */
+ (void) unlink(sock_file);
/* Fill in the socket structure fields */
memset(&sock, 0, sizeof(sock));
@@ -1206,7 +1201,7 @@ static void ctrls_postparse_ev(const void *event_data, void *user_data) {
/* Start listening on the ctrl socket */
PRIVS_ROOT
- ctrls_sockfd = ctrls_listen(ctrls_sock_file, CTRLS_LISTEN_FL_REMOVE_SOCKET);
+ ctrls_sockfd = ctrls_listen(ctrls_sock_file);
PRIVS_RELINQUISH
/* Start a timer for the checking/processing of the ctrl socket. */
@@ -1298,9 +1293,6 @@ static int ctrls_init(void) {
memset(&ctrls_sock_acl, '\0', sizeof(ctrls_acl_t));
ctrls_sock_acl.acl_usrs.allow = ctrls_sock_acl.acl_grps.allow = FALSE;
- /* Start listening on the ctrl socket */
- ctrls_sockfd = ctrls_listen(ctrls_sock_file, 0);
-
pr_event_register(&ctrls_module, "core.restart", ctrls_restart_ev, NULL);
pr_event_register(&ctrls_module, "core.shutdown", ctrls_shutdown_ev, NULL);
pr_event_register(&ctrls_module, "core.postparse", ctrls_postparse_ev, NULL);

View File

@ -1,23 +0,0 @@
From ee528a5c6513932c6dbe7cf69fdcda3fbf009621 Mon Sep 17 00:00:00 2001
From: Paul Howarth <paul@city-fan.org>
Date: Wed, 19 Apr 2017 15:23:30 +0100
Subject: [PATCH] fsio: fix test in xattr-copying loop
Fixes segfaults in fsio file copying tests (Issue #483)
---
src/fsio.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/fsio.c b/src/fsio.c
index a54c64d..91ad0d7 100644
--- a/src/fsio.c
+++ b/src/fsio.c
@@ -2063,7 +2063,7 @@ int pr_fs_copy_file2(const char *src, const char *dst, int flags,
const char **names;
names = xattrs->elts;
- for (i = 0; xattrs->nelts; i++) {
+ for (i = 0; i < xattrs->nelts; i++) {
ssize_t valsz;
/* First, find out how much memory we need for this attribute's

View File

@ -1,206 +0,0 @@
From 389cc579bc8d5704f9dcc2fd01ffd6307aee6b2b Mon Sep 17 00:00:00 2001
From: TJ Saunders <tj@castaglia.org>
Date: Mon, 17 Apr 2017 20:01:47 -0700
Subject: [PATCH] Address some nits in the unit tests, to help make more
repeatable builds on the variety of testing platforms; addresses Issue #483.
---
tests/api/data.c | 5 +++--
tests/api/fsio.c | 28 ++++++++++++++++++++--------
tests/api/inet.c | 19 ++++++++++---------
tests/api/pool.c | 7 ++++++-
4 files changed, 39 insertions(+), 20 deletions(-)
diff --git a/tests/api/data.c b/tests/api/data.c
index e4442ab..223a3af 100644
--- a/tests/api/data.c
+++ b/tests/api/data.c
@@ -313,8 +313,9 @@ START_TEST (data_sendfile_test) {
mark_point();
res = pr_data_sendfile(fd, &offset, strlen(text));
if (res < 0) {
- fail_unless(errno == ENOTSOCK, "Expected ENOTSOCK (%d), got %s (%d)",
- ENOTSOCK, strerror(errno), errno);
+ fail_unless(errno == ENOTSOCK || errno == EINVAL,
+ "Expected ENOTSOCK (%d) or EINVAL (%d), got %s (%d)", ENOTSOCK, EINVAL,
+ strerror(errno), errno);
}
(void) close(fd);
diff --git a/tests/api/fsio.c b/tests/api/fsio.c
index 508ca46..4677d8f 100644
--- a/tests/api/fsio.c
+++ b/tests/api/fsio.c
@@ -34,6 +34,8 @@ static const char *fsio_test2_path = "/tmp/prt-foo.bar.baz.quxx.quzz";
static const char *fsio_unlink_path = "/tmp/prt-fsio-link.dat";
static const char *fsio_link_path = "/tmp/prt-fsio-symlink.lnk";
static const char *fsio_testdir_path = "/tmp/prt-fsio-test.d";
+static const char *fsio_copy_src_path = "/tmp/prt-fs-src.dat";
+static const char *fsio_copy_dst_path = "/tmp/prt-fs-dst.dat";
/* Fixtures */
@@ -1010,8 +1012,12 @@ START_TEST (fsio_sys_access_dir_test) {
strerror(errno));
if (getenv("TRAVIS") == NULL) {
- uid_t other_uid = 1000;
- gid_t other_gid = 1000;
+ uid_t other_uid;
+ gid_t other_gid;
+
+ /* Deliberately use IDs other than the current ones. */
+ other_uid = uid - 1;
+ other_gid = gid - 1;
/* Next, check that others can access the directory. */
pr_fs_clear_cache2(fsio_testdir_path);
@@ -3297,7 +3303,7 @@ END_TEST
START_TEST (fs_copy_file_test) {
int res;
- char *src_path, *dst_path, *text;
+ char *src_path = NULL, *dst_path = NULL, *text;
pr_fh_t *fh;
res = pr_fs_copy_file(NULL, NULL);
@@ -3305,15 +3311,15 @@ START_TEST (fs_copy_file_test) {
fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
strerror(errno), errno);
- src_path = "/tmp/prt-fs-src.dat";
+ src_path = fsio_copy_src_path;
res = pr_fs_copy_file(src_path, NULL);
fail_unless(res < 0, "Failed to handle null destination path");
fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
strerror(errno), errno);
- dst_path = "/tmp/prt-fs-dst.dat";
+ dst_path = fsio_copy_dst_path;
res = pr_fs_copy_file(src_path, dst_path);
- fail_unless(res < 0, "Failed to handle null destination path");
+ fail_unless(res < 0, "Failed to handle nonexistent source path");
fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
strerror(errno), errno);
@@ -3322,6 +3328,7 @@ START_TEST (fs_copy_file_test) {
fail_unless(errno == EISDIR, "Expected EISDIR (%d), got %s (%d)", EISDIR,
strerror(errno), errno);
+ (void) unlink(src_path);
fh = pr_fsio_open(src_path, O_CREAT|O_EXCL|O_WRONLY);
fail_unless(fh != NULL, "Failed to open '%s': %s", src_path, strerror(errno));
@@ -3347,6 +3354,8 @@ START_TEST (fs_copy_file_test) {
res = pr_fs_copy_file(src_path, src_path);
fail_unless(res == 0, "Failed to copy file to itself: %s", strerror(errno));
+ (void) unlink(dst_path);
+
mark_point();
res = pr_fs_copy_file(src_path, dst_path);
fail_unless(res == 0, "Failed to copy file: %s", strerror(errno));
@@ -3366,10 +3375,13 @@ START_TEST (fs_copy_file2_test) {
char *src_path, *dst_path, *text;
pr_fh_t *fh;
- src_path = "/tmp/prt-fs-src.dat";
- dst_path = "/tmp/prt-fs-dst.dat";
+ src_path = fsio_copy_src_path;
+ dst_path = fsio_copy_dst_path;
flags = PR_FSIO_COPY_FILE_FL_NO_DELETE_ON_FAILURE;
+ (void) unlink(src_path);
+ (void) unlink(dst_path);
+
fh = pr_fsio_open(src_path, O_CREAT|O_EXCL|O_WRONLY);
fail_unless(fh != NULL, "Failed to open '%s': %s", src_path, strerror(errno));
diff --git a/tests/api/inet.c b/tests/api/inet.c
index b75c839..03c4781 100644
--- a/tests/api/inet.c
+++ b/tests/api/inet.c
@@ -508,7 +508,7 @@ START_TEST (inet_connect_ipv4_test) {
conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
- res = pr_inet_connect(p, conn, NULL, 80);
+ res = pr_inet_connect(p, conn, NULL, 180);
fail_unless(res < 0, "Failed to handle null address");
fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
strerror(errno), errno);
@@ -517,8 +517,8 @@ START_TEST (inet_connect_ipv4_test) {
fail_unless(addr != NULL, "Failed to resolve '127.0.0.1': %s",
strerror(errno));
- res = pr_inet_connect(p, conn, addr, 80);
- fail_unless(res < 0, "Connected to 127.0.0.1#80 unexpectedly");
+ res = pr_inet_connect(p, conn, addr, 180);
+ fail_unless(res < 0, "Connected to 127.0.0.1#180 unexpectedly");
fail_unless(errno == ECONNREFUSED, "Expected ECONNREFUSED (%d), got %s (%d)",
ECONNREFUSED, strerror(errno), errno);
@@ -573,8 +573,8 @@ START_TEST (inet_connect_ipv6_test) {
fail_unless(addr != NULL, "Failed to resolve '::1': %s",
strerror(errno));
- res = pr_inet_connect(p, conn, addr, 80);
- fail_unless(res < 0, "Connected to ::1#80 unexpectedly");
+ res = pr_inet_connect(p, conn, addr, 180);
+ fail_unless(res < 0, "Connected to ::1#180 unexpectedly");
fail_unless(errno == ECONNREFUSED || errno == ENETUNREACH || errno == EADDRNOTAVAIL,
"Expected ECONNREFUSED (%d), ENETUNREACH (%d), or EADDRNOTAVAIL (%d), got %s (%d)",
ECONNREFUSED, ENETUNREACH, EADDRNOTAVAIL, strerror(errno), errno);
@@ -637,7 +637,7 @@ START_TEST (inet_connect_nowait_test) {
conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
- res = pr_inet_connect_nowait(p, conn, NULL, 80);
+ res = pr_inet_connect_nowait(p, conn, NULL, 180);
fail_unless(res < 0, "Failed to handle null address");
fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
strerror(errno), errno);
@@ -646,8 +646,8 @@ START_TEST (inet_connect_nowait_test) {
fail_unless(addr != NULL, "Failed to resolve '127.0.0.1': %s",
strerror(errno));
- res = pr_inet_connect_nowait(p, conn, addr, 80);
- fail_unless(res != -1, "Connected to 127.0.0.1#80 unexpectedly");
+ res = pr_inet_connect_nowait(p, conn, addr, 180);
+ fail_unless(res != -1, "Connected to 127.0.0.1#180 unexpectedly");
/* Try connecting to Google's DNS server. */
@@ -657,7 +657,8 @@ START_TEST (inet_connect_nowait_test) {
res = pr_inet_connect_nowait(p, conn, addr, 53);
if (res < 0 &&
- errno != ECONNREFUSED) {
+ errno != ECONNREFUSED &&
+ errno != EBADF) {
fail_unless(res != -1, "Failed to connect to 8.8.8.8#53: %s",
strerror(errno));
}
diff --git a/tests/api/pool.c b/tests/api/pool.c
index 8008f1c..d2f4c0d 100644
--- a/tests/api/pool.c
+++ b/tests/api/pool.c
@@ -52,12 +52,17 @@ START_TEST (pool_destroy_pool_test) {
p = make_sub_pool(permanent_pool);
destroy_pool(p);
-#if !defined(PR_USE_DEVEL)
/* What happens if we destroy an already-destroyed pool? Answer: IFF
* --enable-devel was used, THEN destroying an already-destroyed pool
* will result in an exit(2) call from within pool.c, via the
* chk_on_blk_list() function. How impolite.
+ *
+ * And if --enable-devel was NOT used, on SOME systems, this test tickles
+ * other libc/malloc/free behaviors, which are unsettling.
+ *
+ * Sigh. So for now, I'll just leave this here, but commented out.
*/
+#if 0
mark_point();
destroy_pool(p);
#endif

View File

@ -1,326 +0,0 @@
From 41ecb7dc3932dd57bac52980982c76bf036ccfd8 Mon Sep 17 00:00:00 2001
From: TJ Saunders <tj@castaglia.org>
Date: Wed, 12 Jul 2017 23:14:59 -0700
Subject: [PATCH] Bug#4309: Allow SFTP/SCP logins to succeed properly when
"AllowEmptyPasswords off" in effect.
Also ensure that a truly empty SFTP/SCP password IS properly rejected in such
a configuration.
---
contrib/mod_sftp/auth-password.c | 41 +++++++-
modules/mod_auth.c | 55 +++++++----
tests/t/lib/ProFTPD/Tests/Modules/mod_sftp.pm | 132 ++++++++++++++++++++++++++
3 files changed, 205 insertions(+), 23 deletions(-)
diff --git a/contrib/mod_sftp/auth-password.c b/contrib/mod_sftp/auth-password.c
index 2605af7f6..8fb9804bd 100644
--- a/contrib/mod_sftp/auth-password.c
+++ b/contrib/mod_sftp/auth-password.c
@@ -1,6 +1,6 @@
/*
* ProFTPD - mod_sftp 'password' user authentication
- * Copyright (c) 2008-2015 TJ Saunders
+ * Copyright (c) 2008-2017 TJ Saunders
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -37,6 +37,7 @@ int sftp_auth_password(struct ssh2_packet *pkt, cmd_rec *pass_cmd,
char *passwd;
int have_new_passwd, res;
struct passwd *pw;
+ size_t passwd_len;
cipher_algo = sftp_cipher_get_read_algo();
mac_algo = sftp_mac_get_read_algo();
@@ -77,6 +78,7 @@ int sftp_auth_password(struct ssh2_packet *pkt, cmd_rec *pass_cmd,
passwd = sftp_msg_read_string(pkt->pool, buf, buflen);
passwd = sftp_utf8_decode_str(pkt->pool, passwd);
+ passwd_len = strlen(passwd);
pass_cmd->arg = passwd;
@@ -92,7 +94,7 @@ int sftp_auth_password(struct ssh2_packet *pkt, cmd_rec *pass_cmd,
pr_cmd_dispatch_phase(pass_cmd, POST_CMD_ERR, 0);
pr_cmd_dispatch_phase(pass_cmd, LOG_CMD_ERR, 0);
- pr_memscrub(passwd, strlen(passwd));
+ pr_memscrub(passwd, passwd_len);
*send_userauth_fail = TRUE;
errno = EPERM;
@@ -109,15 +111,46 @@ int sftp_auth_password(struct ssh2_packet *pkt, cmd_rec *pass_cmd,
session.c->remote_name, pr_netaddr_get_ipstr(session.c->remote_addr),
pr_netaddr_get_ipstr(session.c->local_addr), session.c->local_port);
- pr_memscrub(passwd, strlen(passwd));
+ pr_memscrub(passwd, passwd_len);
*send_userauth_fail = TRUE;
errno = ENOENT;
return 0;
}
+ if (passwd_len == 0) {
+ config_rec *c;
+ int allow_empty_passwords = TRUE;
+
+ c = find_config(main_server->conf, CONF_PARAM, "AllowEmptyPasswords",
+ FALSE);
+ if (c != NULL) {
+ allow_empty_passwords = *((int *) c->argv[0]);
+ }
+
+ if (allow_empty_passwords == FALSE) {
+ pr_log_debug(DEBUG5,
+ "Refusing empty password from user '%s' (AllowEmptyPasswords false)",
+ user);
+ pr_log_auth(PR_LOG_NOTICE,
+ "Refusing empty password from user '%s'", user);
+
+ pr_event_generate("mod_auth.empty-password", user);
+ pr_response_add_err(R_501, "Login incorrect.");
+
+ pr_cmd_dispatch_phase(pass_cmd, POST_CMD_ERR, 0);
+ pr_cmd_dispatch_phase(pass_cmd, LOG_CMD_ERR, 0);
+
+ pr_memscrub(passwd, passwd_len);
+
+ *send_userauth_fail = TRUE;
+ errno = EPERM;
+ return 0;
+ }
+ }
+
res = pr_auth_authenticate(pkt->pool, user, passwd);
- pr_memscrub(passwd, strlen(passwd));
+ pr_memscrub(passwd, passwd_len);
switch (res) {
case PR_AUTH_OK:
diff --git a/modules/mod_auth.c b/modules/mod_auth.c
index 2b76070f7..b60cea5a9 100644
--- a/modules/mod_auth.c
+++ b/modules/mod_auth.c
@@ -2636,35 +2636,52 @@ MODRET auth_pre_pass(cmd_rec *cmd) {
allow_empty_passwords = *((int *) c->argv[0]);
if (allow_empty_passwords == FALSE) {
+ const char *proto;
+ int reject_empty_passwd = FALSE, using_ssh2 = FALSE;
size_t passwd_len = 0;
+ proto = pr_session_get_protocol(0);
+ if (strcmp(proto, "ssh2") == 0) {
+ using_ssh2 = TRUE;
+ }
+
if (cmd->argc > 1) {
if (cmd->arg != NULL) {
passwd_len = strlen(cmd->arg);
}
}
- /* Make sure to NOT enforce 'AllowEmptyPasswords off' if e.g.
- * the AllowDotLogin TLSOption is in effect.
- */
- if (cmd->argc == 1 ||
- passwd_len == 0) {
-
- if (session.auth_mech == NULL ||
- strcmp(session.auth_mech, "mod_tls.c") != 0) {
- pr_log_debug(DEBUG5,
- "Refusing empty password from user '%s' (AllowEmptyPasswords "
- "false)", user);
- pr_log_auth(PR_LOG_NOTICE,
- "Refusing empty password from user '%s'", user);
-
- pr_event_generate("mod_auth.empty-password", user);
- pr_response_add_err(R_501, _("Login incorrect."));
- return PR_ERROR(cmd);
+ if (passwd_len == 0) {
+ reject_empty_passwd = TRUE;
+
+ /* Make sure to NOT enforce 'AllowEmptyPasswords off' if e.g.
+ * the AllowDotLogin TLSOption is in effect, or if the protocol is
+ * SSH2 (for mod_sftp uses "fake" PASS commands for the SSH login
+ * protocol).
+ */
+
+ if (session.auth_mech != NULL &&
+ strcmp(session.auth_mech, "mod_tls.c") == 0) {
+ pr_log_debug(DEBUG9, "%s", "'AllowEmptyPasswords off' in effect, "
+ "BUT client authenticated via the AllowDotLogin TLSOption");
+ reject_empty_passwd = FALSE;
}
- pr_log_debug(DEBUG9, "%s", "'AllowEmptyPasswords off' in effect, "
- "BUT client authenticated via the AllowDotLogin TLSOption");
+ if (using_ssh2 == TRUE) {
+ reject_empty_passwd = FALSE;
+ }
+ }
+
+ if (reject_empty_passwd == TRUE) {
+ pr_log_debug(DEBUG5,
+ "Refusing empty password from user '%s' (AllowEmptyPasswords "
+ "false)", user);
+ pr_log_auth(PR_LOG_NOTICE,
+ "Refusing empty password from user '%s'", user);
+
+ pr_event_generate("mod_auth.empty-password", user);
+ pr_response_add_err(R_501, _("Login incorrect."));
+ return PR_ERROR(cmd);
}
}
}
diff --git a/tests/t/lib/ProFTPD/Tests/Modules/mod_sftp.pm b/tests/t/lib/ProFTPD/Tests/Modules/mod_sftp.pm
index c919844ea..c608e76fc 100644
--- a/tests/t/lib/ProFTPD/Tests/Modules/mod_sftp.pm
+++ b/tests/t/lib/ProFTPD/Tests/Modules/mod_sftp.pm
@@ -1279,6 +1279,11 @@ my $TESTS = {
test_class => [qw(bug forking sftp ssh2)],
},
+ sftp_config_allow_empty_passwords_off_bug4309 => {
+ order => ++$order,
+ test_class => [qw(bug forking sftp ssh2)],
+ },
+
sftp_multi_channels => {
order => ++$order,
test_class => [qw(forking sftp ssh2)],
@@ -41885,6 +41890,133 @@ sub sftp_config_insecure_hostkey_perms_bug4098 {
test_cleanup($setup->{log_file}, $ex);
}
+sub sftp_config_allow_empty_passwords_off_bug4309 {
+ my $self = shift;
+ my $tmpdir = $self->{tmpdir};
+ my $setup = test_setup($tmpdir, 'sftp');
+
+ my $other_user = 'nopassword';
+ my $other_passwd = '';
+ my $other_uid = 1000;
+ my $other_gid = 1000;
+
+ auth_user_write($setup->{auth_user_file}, $other_user, $other_passwd,
+ $other_uid, $other_gid, $setup->{home_dir}, '/bin/bash');
+ auth_group_write($setup->{auth_group_file}, $setup->{group}, $setup->{gid},
+ $other_user);
+
+ my $rsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_rsa_key');
+ my $dsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_dsa_key');
+
+ my $config = {
+ PidFile => $setup->{pid_file},
+ ScoreboardFile => $setup->{scoreboard_file},
+ SystemLog => $setup->{log_file},
+ TraceLog => $setup->{log_file},
+ Trace => 'DEFAULT:10 ssh2:20 sftp:20',
+
+ AuthUserFile => $setup->{auth_user_file},
+ AuthGroupFile => $setup->{auth_group_file},
+
+ IfModules => {
+ 'mod_delay.c' => {
+ DelayEngine => 'off',
+ },
+
+ 'mod_sftp.c' => [
+ "SFTPEngine on",
+ "SFTPLog $setup->{log_file}",
+ "SFTPHostKey $rsa_host_key",
+ "SFTPHostKey $dsa_host_key",
+ "AllowEmptyPasswords off",
+ ],
+ },
+ };
+
+ my ($port, $config_user, $config_group) = config_write($setup->{config_file},
+ $config);
+
+ # Open pipes, for use between the parent and child processes. Specifically,
+ # the child will indicate when it's done with its test by writing a message
+ # to the parent.
+ my ($rfh, $wfh);
+ unless (pipe($rfh, $wfh)) {
+ die("Can't open pipe: $!");
+ }
+
+ require Net::SSH2;
+
+ my $ex;
+
+ # Fork child
+ $self->handle_sigchld();
+ defined(my $pid = fork()) or die("Can't fork: $!");
+ if ($pid) {
+ eval {
+ my $ssh2 = Net::SSH2->new();
+
+ sleep(1);
+
+ # First, we'll try to login with normal user/password; this should
+ # succeed.
+ unless ($ssh2->connect('127.0.0.1', $port)) {
+ my ($err_code, $err_name, $err_str) = $ssh2->error();
+ die("Can't connect to SSH2 server: [$err_name] ($err_code) $err_str");
+ }
+
+ unless ($ssh2->auth_password($setup->{user}, $setup->{passwd})) {
+ my ($err_code, $err_name, $err_str) = $ssh2->error();
+ die("Can't login to SSH2 server: [$err_name] ($err_code) $err_str");
+ }
+
+ my $sftp = $ssh2->sftp();
+ unless ($sftp) {
+ my ($err_code, $err_name, $err_str) = $ssh2->error();
+ die("Can't use SFTP on SSH2 server: [$err_name] ($err_code) $err_str");
+ }
+
+ $sftp = undef;
+ $ssh2->disconnect();
+ $ssh2 = undef;
+
+ # Then, we'll try to login with an empty password; this should fail.
+
+ $ssh2 = Net::SSH2->new();
+ unless ($ssh2->connect('127.0.0.1', $port)) {
+ my ($err_code, $err_name, $err_str) = $ssh2->error();
+ die("Can't connect to SSH2 server: [$err_name] ($err_code) $err_str");
+ }
+
+ if ($ssh2->auth_password($other_user, $other_passwd)) {
+ die("Login with empty password succeeded unexpectedly");
+ }
+
+ $ssh2->disconnect();
+ };
+ if ($@) {
+ $ex = $@;
+ }
+
+ $wfh->print("done\n");
+ $wfh->flush();
+
+ } else {
+ eval { server_wait($setup->{config_file}, $rfh) };
+ if ($@) {
+ warn($@);
+ exit 1;
+ }
+
+ exit 0;
+ }
+
+ # Stop server
+ server_stop($setup->{pid_file});
+ $self->assert_child_ok($pid);
+
+ test_cleanup($setup->{log_file}, $ex);
+}
+
sub sftp_multi_channel_downloads {
my $self = shift;
my $tmpdir = $self->{tmpdir};

View File

@ -1,31 +0,0 @@
From 459693c70c83b7d173ec10bb8089d4ce4e59d301 Mon Sep 17 00:00:00 2001
From: TJ Saunders <tj@castaglia.org>
Date: Tue, 2 May 2017 19:56:39 -0700
Subject: [PATCH] Bug#4306: AllowChrootSymlinks off could cause login failures
depending on filesystem permissions.
Use the IDs of the logging-in user to perform the directory walk, looking
for symlinks, to be more consistent with similar checks done during login.
---
modules/mod_auth.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/modules/mod_auth.c b/modules/mod_auth.c
index d93c630..2b76070 100644
--- a/modules/mod_auth.c
+++ b/modules/mod_auth.c
@@ -936,9 +936,13 @@ static int get_default_root(pool *p, int allow_symlinks, const char **root) {
path[pathlen-1] = '\0';
}
+ PRIVS_USER
res = is_symlink_path(p, path, pathlen);
+ xerrno = errno;
+ PRIVS_RELINQUISH
+
if (res < 0) {
- if (errno == EPERM) {
+ if (xerrno == EPERM) {
pr_log_pri(PR_LOG_WARNING, "error: DefaultRoot %s is a symlink "
"(denied by AllowChrootSymlinks config)", path);
}

View File

@ -1,37 +0,0 @@
From 48012e5ab7969fc77d0724769b1e737343ed654d Mon Sep 17 00:00:00 2001
From: Paul Howarth <paul@city-fan.org>
Date: Wed, 10 May 2017 10:10:40 +0100
Subject: [PATCH] Switch to Type = simple and add configuration test
Upstream recommends Type = simple if possible rather than Type = forking:
http://0pointer.de/public/systemd-man/daemon.html#Integration%20with%20Systemd
Also add configuration test prior to starting the daemon, to help diagnose
start-up problems.
---
contrib/dist/rpm/proftpd.service | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/contrib/dist/rpm/proftpd.service b/contrib/dist/rpm/proftpd.service
index 07802ca..8a4df33 100644
--- a/contrib/dist/rpm/proftpd.service
+++ b/contrib/dist/rpm/proftpd.service
@@ -3,14 +3,13 @@ Description = ProFTPD FTP Server
After = network.target nss-lookup.target local-fs.target remote-fs.target
[Service]
-Type = forking
-PIDFile = /run/proftpd/proftpd.pid
+Type = simple
Environment = PROFTPD_OPTIONS=
EnvironmentFile = -/etc/sysconfig/proftpd
-ExecStart = /usr/sbin/proftpd $PROFTPD_OPTIONS
-ExecStartPost = /usr/bin/touch /var/lock/subsys/proftpd
-ExecStopPost = /bin/rm -f /var/lock/subsys/proftpd
+ExecStartPre = /usr/sbin/proftpd --configtest
+ExecStart = /usr/sbin/proftpd --nodaemon $PROFTPD_OPTIONS
ExecReload = /bin/kill -HUP $MAINPID
+PIDFile = /run/proftpd/proftpd.pid
[Install]
WantedBy = multi-user.target

View File

@ -1,66 +0,0 @@
From 73887e02dbcc9e6e94b26f30c3ef89acb8016f2d Mon Sep 17 00:00:00 2001
From: TJ Saunders <tj@castaglia.org>
Date: Sun, 21 May 2017 13:25:50 -0700
Subject: [PATCH] Merge pull request #510 from pghmcfc/32-bit-fixes
32 bit fixes
---
src/trace.c | 16 ++++++++++++++++
tests/api/misc.c | 2 +-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/src/trace.c b/src/trace.c
index 1c29cc6bf..dc22e9e89 100644
--- a/src/trace.c
+++ b/src/trace.c
@@ -273,7 +273,13 @@ int pr_trace_parse_levels(char *str, int *min_level, int *max_level) {
ptr = strchr(str, '-');
if (ptr == NULL) {
/* Just a single value. */
+ errno = 0;
high = (int) strtol(str, &ptr, 10);
+ if (errno == ERANGE) {
+ errno = EINVAL;
+ return -1;
+ }
+
if (ptr && *ptr) {
errno = EINVAL;
return -1;
@@ -302,6 +308,11 @@ int pr_trace_parse_levels(char *str, int *min_level, int *max_level) {
*ptr = '\0';
low = (int) strtol(str, &tmp, 10);
+ if (errno == ERANGE) {
+ errno = EINVAL;
+ return -1;
+ }
+
if (tmp && *tmp) {
*ptr = '-';
errno = EINVAL;
@@ -316,6 +327,11 @@ int pr_trace_parse_levels(char *str, int *min_level, int *max_level) {
tmp = NULL;
high = (int) strtol(ptr + 1, &tmp, 10);
+ if (errno == ERANGE) {
+ errno = EINVAL;
+ return -1;
+ }
+
if (tmp && *tmp) {
errno = EINVAL;
return -1;
diff --git a/tests/api/misc.c b/tests/api/misc.c
index 16d56cb71..926d9b3e3 100644
--- a/tests/api/misc.c
+++ b/tests/api/misc.c
@@ -702,7 +702,7 @@ START_TEST (check_shutmsg_test) {
(void) unlink(path);
res = write_shutmsg(path,
- "2340 1 1 0 0 0 0000 0000\nGoodbye, cruel world!\n");
+ "2037 1 1 0 0 0 0000 0000\nGoodbye, cruel world!\n");
fail_unless(res == 0, "Failed to write '%s': %s", path, strerror(errno));
mark_point();

View File

@ -1,119 +0,0 @@
From 757b9633191eafa32a86ab8ec032e743d0227093 Mon Sep 17 00:00:00 2001
From: TJ Saunders <tj@castaglia.org>
Date: Wed, 5 Jul 2017 23:33:16 -0700
Subject: [PATCH] Bug#4308: When authorizing a user, check for any shadow
information for that user, and use such information as part of the
authorization check.
---
modules/mod_auth_unix.c | 67 +++++++++++++++++++++++++++++++++++++++----------
1 file changed, 54 insertions(+), 13 deletions(-)
diff --git a/modules/mod_auth_unix.c b/modules/mod_auth_unix.c
index 788b4c549..7d7a994d7 100644
--- a/modules/mod_auth_unix.c
+++ b/modules/mod_auth_unix.c
@@ -715,34 +715,40 @@ static char *get_pwd_info(pool *p, const char *u, time_t *lstchg, time_t *min,
MODRET pw_auth(cmd_rec *cmd) {
int res;
time_t now;
- char *cpw;
- time_t lstchg = -1, max = -1, inact = -1, disable = -1;
+ char *cleartxt_passwd;
+ time_t lstchg = -1, max = -1, inact = -1, expire = -1;
const char *name;
+ size_t cleartxt_passwdlen;
name = cmd->argv[0];
- time(&now);
- cpw = get_pwd_info(cmd->tmp_pool, name, &lstchg, NULL, &max, NULL, &inact,
- &disable);
- if (cpw == NULL) {
+ cleartxt_passwd = get_pwd_info(cmd->tmp_pool, name, &lstchg, NULL, &max,
+ NULL, &inact, &expire);
+ if (cleartxt_passwd == NULL) {
return PR_DECLINED(cmd);
}
- res = pr_auth_check(cmd->tmp_pool, cpw, cmd->argv[0], cmd->argv[1]);
+ res = pr_auth_check(cmd->tmp_pool, cleartxt_passwd, cmd->argv[0],
+ cmd->argv[1]);
+ cleartxt_passwdlen = strlen(cleartxt_passwd);
+ pr_memscrub(cleartxt_passwd, cleartxt_passwdlen);
+
if (res < PR_AUTH_OK) {
return PR_ERROR_INT(cmd, res);
}
+ time(&now);
+
if (lstchg > (time_t) 0 &&
max > (time_t) 0 &&
inact > (time_t) 0) {
- if (now > lstchg + max + inact) {
+ if (now > (lstchg + max + inact)) {
return PR_ERROR_INT(cmd, PR_AUTH_AGEPWD);
}
}
- if (disable > (time_t) 0 &&
- now > disable) {
+ if (expire > (time_t) 0 &&
+ now > expire) {
return PR_ERROR_INT(cmd, PR_AUTH_DISABLEDPWD);
}
@@ -751,14 +757,49 @@ MODRET pw_auth(cmd_rec *cmd) {
}
MODRET pw_authz(cmd_rec *cmd) {
+ time_t now;
+ char *user, *cleartxt_passwd;
+ time_t lstchg = -1, max = -1, inact = -1, expire = -1;
+ size_t cleartxt_passwdlen;
+
+ user = cmd->argv[0];
+
+ cleartxt_passwd = get_pwd_info(cmd->tmp_pool, user, &lstchg, NULL, &max,
+ NULL, &inact, &expire);
+ if (cleartxt_passwd == NULL) {
+ pr_log_auth(LOG_WARNING, "no password information found for user '%.100s'",
+ user);
+ return PR_ERROR_INT(cmd, PR_AUTH_NOPWD);
+ }
+
+ cleartxt_passwdlen = strlen(cleartxt_passwd);
+ pr_memscrub(cleartxt_passwd, cleartxt_passwdlen);
+
+ time(&now);
+
+ if (lstchg > (time_t) 0 &&
+ max > (time_t) 0 &&
+ inact > (time_t) 0) {
+ if (now > (lstchg + max + inact)) {
+ pr_log_auth(LOG_WARNING,
+ "account for user '%.100s' disabled due to inactivity", user);
+ return PR_ERROR_INT(cmd, PR_AUTH_AGEPWD);
+ }
+ }
+
+ if (expire > (time_t) 0 &&
+ now > expire) {
+ pr_log_auth(LOG_WARNING,
+ "account for user '%.100s' disabled due to password expiration", user);
+ return PR_ERROR_INT(cmd, PR_AUTH_DISABLEDPWD);
+ }
+
/* XXX Any other implementations here? */
#ifdef HAVE_LOGINRESTRICTIONS
if (!(auth_unix_opts & AUTH_UNIX_OPT_AIX_NO_RLOGIN)) {
int res, xerrno, code = 0;
- char *user = NULL, *reason = NULL;
-
- user = cmd->argv[0];
+ char *reason = NULL;
/* Check for account login restrictions and such using AIX-specific
* functions.

View File

@ -1,47 +0,0 @@
From 925ee5b8f636ab2fd5a3e02af79ba49f54a85b8d Mon Sep 17 00:00:00 2001
From: Paul Howarth <paul@city-fan.org>
Date: Fri, 5 May 2017 15:38:59 +0100
Subject: [PATCH] Don't touch TLSCipherSuite when using system profiles
Fedora and possibly other Linux distributions support system-wide
crypto policies to enable sane defaults to be specified in an ever
changing world of different cipher recommendations. In order to use
such a policy, OpenSSL users just set their cipher selection to
"PROFILE=SYSTEM", and the system-wide policy will be selected
(which can itself be set to various values, for best compatibility,
best strength, a compromise of the two, etc.).
See:
https://fedoraproject.org/wiki/Packaging:CryptoPolicies
https://fedoraproject.org/wiki/Changes/CryptoPolicy
The "PROFILE=SYSTEM" string cannot be used in conjunction with other
cipher selections, so prepending it with "!EXPORT:" results in:
mod_tls/2.7[xxxxx]: unable to accept TLS connection: client does not support
any cipher from 'TLSCipherSuite !EXPORT:PROFILE=SYSTEM' (see `openssl ciphers
!EXPORT:PROFILE=SYSTEM` for full list)
Hence, do not touch the supplied TLSCipherSuite if it starts with "PROFILE=".
---
contrib/mod_tls.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/contrib/mod_tls.c b/contrib/mod_tls.c
index 3ff8ee2..c38ecac 100644
--- a/contrib/mod_tls.c
+++ b/contrib/mod_tls.c
@@ -11985,7 +11985,12 @@ MODRET set_tlsciphersuite(cmd_rec *cmd) {
c = add_config_param(cmd->argv[0], 1, NULL);
/* Make sure that EXPORT ciphers cannot be used, per Bug#4163. */
- ciphersuite = pstrcat(c->pool, "!EXPORT:", ciphersuite, NULL);
+ /* This breaks system profiles though, so don't change them. */
+ if (strncmp(ciphersuite, "PROFILE=", 8) == 0) {
+ ciphersuite = pstrdup(c->pool, ciphersuite);
+ } else {
+ ciphersuite = pstrcat(c->pool, "!EXPORT:", ciphersuite, NULL);
+ }
/* Check that our construct ciphersuite is acceptable. */
ctx = SSL_CTX_new(SSLv23_server_method());

View File

@ -1,147 +0,0 @@
From 2f563aa12cf1ed199671821e2fba7088ab36b681 Mon Sep 17 00:00:00 2001
From: Paul Howarth <paul@city-fan.org>
Date: Thu, 18 May 2017 15:38:46 +0100
Subject: [PATCH] Use /etc/hosts rather than /etc/resolv.conf in fsio unit
tests
The fsio unit tests require a read-only system file to test that
files can be read, can't be written or deleted etc. The file
/etc/resolv.conf is currently used for this, but does not exist
in the minimum build environment used on Fedora's koji build
servers, resulting in test failures. Using /etc/hosts, which does
exist there and should be equally ubiquitous, fixes this issue.
---
tests/api/fsio.c | 40 ++++++++++++++++++++--------------------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/tests/api/fsio.c b/tests/api/fsio.c
index bacd306..3cb1741 100644
--- a/tests/api/fsio.c
+++ b/tests/api/fsio.c
@@ -119,8 +119,8 @@ START_TEST (fsio_sys_open_test) {
mark_point();
flags = O_RDONLY;
- fh = pr_fsio_open("/etc/resolv.conf", flags);
- fail_unless(fh != NULL, "Failed to /etc/resolv.conf: %s", strerror(errno));
+ fh = pr_fsio_open("/etc/hosts", flags);
+ fail_unless(fh != NULL, "Failed to open /etc/hosts: %s", strerror(errno));
(void) pr_fsio_close(fh);
}
@@ -144,8 +144,8 @@ START_TEST (fsio_sys_open_canon_test) {
strerror(errno), errno);
flags = O_RDONLY;
- fh = pr_fsio_open_canon("/etc/resolv.conf", flags);
- fail_unless(fh != NULL, "Failed to /etc/resolv.conf: %s", strerror(errno));
+ fh = pr_fsio_open_canon("/etc/hosts", flags);
+ fail_unless(fh != NULL, "Failed to open /etc/hosts: %s", strerror(errno));
(void) pr_fsio_close(fh);
}
@@ -159,7 +159,7 @@ START_TEST (fsio_sys_open_chroot_guard_test) {
res = pr_fsio_guard_chroot(TRUE);
fail_unless(res == FALSE, "Expected FALSE (%d), got %d", FALSE, res);
- path = "/etc/resolv.conf";
+ path = "/etc/hosts";
flags = O_CREAT|O_RDONLY;
fh = pr_fsio_open(path, flags);
if (fh != NULL) {
@@ -203,7 +203,7 @@ START_TEST (fsio_sys_open_chroot_guard_test) {
(void) pr_fsio_guard_chroot(FALSE);
- path = "/etc/resolv.conf";
+ path = "/etc/hosts";
flags = O_RDONLY;
fh = pr_fsio_open(path, flags);
fail_unless(fh != NULL, "Failed to open '%s': %s", path, strerror(errno));
@@ -220,8 +220,8 @@ START_TEST (fsio_sys_close_test) {
fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s %d", EINVAL,
strerror(errno), errno);
- fh = pr_fsio_open("/etc/resolv.conf", O_RDONLY);
- fail_unless(fh != NULL, "Failed to open /etc/resolv.conf: %s",
+ fh = pr_fsio_open("/etc/hosts", O_RDONLY);
+ fail_unless(fh != NULL, "Failed to open /etc/hosts: %s",
strerror(errno));
res = pr_fsio_close(fh);
@@ -265,8 +265,8 @@ START_TEST (fsio_sys_unlink_chroot_guard_test) {
res = pr_fsio_guard_chroot(TRUE);
fail_unless(res == FALSE, "Expected FALSE (%d), got %d", FALSE, res);
- res = pr_fsio_unlink("/etc/resolv.conf");
- fail_unless(res < 0, "Deleted /etc/resolv.conf unexpectedly");
+ res = pr_fsio_unlink("/etc/hosts");
+ fail_unless(res < 0, "Deleted /etc/hosts unexpectedly");
fail_unless(errno == EACCES, "Expected EACCES (%d), got %s %d", EACCES,
strerror(errno), errno);
@@ -352,12 +352,12 @@ START_TEST (fsio_sys_fstat_test) {
fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
strerror(errno), errno);
- fh = pr_fsio_open("/etc/resolv.conf", O_RDONLY);
- fail_unless(fh != NULL, "Failed to open /etc/resolv.conf: %s",
+ fh = pr_fsio_open("/etc/hosts", O_RDONLY);
+ fail_unless(fh != NULL, "Failed to open /etc/hosts: %s",
strerror(errno));
res = pr_fsio_fstat(fh, &st);
- fail_unless(res == 0, "Failed to fstat /etc/resolv.conf: %s",
+ fail_unless(res == 0, "Failed to fstat /etc/hosts: %s",
strerror(errno));
(void) pr_fsio_close(fh);
}
@@ -374,8 +374,8 @@ START_TEST (fsio_sys_read_test) {
fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
strerror(errno), errno);
- fh = pr_fsio_open("/etc/resolv.conf", O_RDONLY);
- fail_unless(fh != NULL, "Failed to open /etc/resolv.conf: %s",
+ fh = pr_fsio_open("/etc/hosts", O_RDONLY);
+ fail_unless(fh != NULL, "Failed to open /etc/hosts: %s",
strerror(errno));
res = pr_fsio_read(fh, NULL, 0);
@@ -443,8 +443,8 @@ START_TEST (fsio_sys_lseek_test) {
fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
strerror(errno), errno);
- fh = pr_fsio_open("/etc/resolv.conf", O_RDONLY);
- fail_unless(fh != NULL, "Failed to open /etc/resolv.conf: %s",
+ fh = pr_fsio_open("/etc/hosts", O_RDONLY);
+ fail_unless(fh != NULL, "Failed to open /etc/hosts: %s",
strerror(errno));
res = pr_fsio_lseek(fh, 0, 0);
@@ -2083,7 +2083,7 @@ START_TEST (fsio_sys_chdir_test) {
fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
strerror(errno), errno);
- res = pr_fsio_chdir("/etc/resolv.conf", FALSE);
+ res = pr_fsio_chdir("/etc/hosts", FALSE);
fail_unless(res < 0, "Failed to handle file argument");
fail_unless(errno == EINVAL || errno == ENOTDIR,
"Expected EINVAL (%d) or ENOTDIR (%d), got %s (%d)", EINVAL, ENOTDIR,
@@ -2145,7 +2145,7 @@ START_TEST (fsio_sys_opendir_test) {
strerror(errno), errno);
mark_point();
- path = "/etc/resolv.conf";
+ path = "/etc/hosts";
res = pr_fsio_opendir(path);
fail_unless(res == NULL, "Failed to handle file argument");
fail_unless(errno == ENOTDIR, "Expected ENOTDIR (%d), got %s (%d)", ENOTDIR,
@@ -2175,7 +2175,7 @@ START_TEST (fsio_sys_readdir_test) {
fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
strerror(errno), errno);
- dent = pr_fsio_readdir("/etc/resolv.conf");
+ dent = pr_fsio_readdir("/etc/hosts");
fail_unless(dent == NULL, "Failed to handle file argument");
fail_unless(errno == ENOTDIR, "Expected ENOTDIR (%d), got %s (%d)", ENOTDIR,
strerror(errno), errno);

View File

@ -1,58 +0,0 @@
From a2c02a6baf555fea10ea0bccdcc4e632fb9d4711 Mon Sep 17 00:00:00 2001
From: TJ Saunders <tj@castaglia.org>
Date: Sun, 27 May 2018 16:11:24 -0700
Subject: [PATCH] Issue #674: Update mod_sftp to handle changed APIs in OpenSSL
1.1.x releases.
---
contrib/mod_sftp/keys.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/contrib/mod_sftp/keys.c b/contrib/mod_sftp/keys.c
index 19bf8edf5..191dbabb9 100644
--- a/contrib/mod_sftp/keys.c
+++ b/contrib/mod_sftp/keys.c
@@ -1,6 +1,6 @@
/*
* ProFTPD - mod_sftp key mgmt (keys)
- * Copyright (c) 2008-2017 TJ Saunders
+ * Copyright (c) 2008-2018 TJ Saunders
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -2780,7 +2780,7 @@ static const unsigned char *dsa_sign_data(pool *p, const unsigned char *data,
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
!defined(HAVE_LIBRESSL)
- DSA_SIG_get0(&sig_r, &sig_s, sig);
+ DSA_SIG_get0(sig, &sig_r, &sig_s);
#else
sig_r = sig->r;
sig_s = sig->s;
@@ -2960,7 +2960,7 @@ static const unsigned char *ecdsa_sign_data(pool *p, const unsigned char *data,
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
!defined(HAVE_LIBRESSL)
- ECDSA_SIG_get0(&sig_r, &sig_s, sig);
+ ECDSA_SIG_get0(sig, &sig_r, &sig_s);
#else
sig_r = sig->r;
sig_s = sig->s;
@@ -3307,7 +3307,7 @@ int sftp_keys_verify_signed_data(pool *p, const char *pubkey_algo,
dsa_sig = DSA_SIG_new();
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
!defined(HAVE_LIBRESSL)
- DSA_SIG_get0(&sig_r, &sig_s, dsa_sig);
+ DSA_SIG_get0(sig, &sig_r, &sig_s);
#else
sig_r = dsa_sig->r;
sig_s = dsa_sig->s;
@@ -3426,7 +3426,7 @@ int sftp_keys_verify_signed_data(pool *p, const char *pubkey_algo,
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
!defined(HAVE_LIBRESSL)
- ECDSA_SIG_get0(&sig_r, &sig_s, ecdsa_sig);
+ ECDSA_SIG_get0(ecdsa_sig, &sig_r, &sig_s);
#else
sig_r = ecdsa_sig->r;
sig_s = ecdsa_sig->s;

View File

@ -1,159 +0,0 @@
From aa85f127d31346a28c619ee426090f1f23fd2249 Mon Sep 17 00:00:00 2001
From: TJ Saunders <tj@castaglia.org>
Date: Fri, 5 May 2017 09:24:10 -0700
Subject: [PATCH] Improve detection of badly configured ciphersuites (e.g.
unsupported/misspelled cipher suites) at startup time.
---
contrib/mod_tls.c | 21 +++++++++++-
doc/contrib/mod_tls.html | 21 +++++++++++-
tests/t/lib/ProFTPD/Tests/Modules/mod_tls.pm | 50 ++++++++++++++++++++++++++++
3 files changed, 90 insertions(+), 2 deletions(-)
diff --git a/contrib/mod_tls.c b/contrib/mod_tls.c
index 7a2a74f..3ff8ee2 100644
--- a/contrib/mod_tls.c
+++ b/contrib/mod_tls.c
@@ -11976,6 +11976,7 @@ MODRET set_tlscertchain(cmd_rec *cmd) {
MODRET set_tlsciphersuite(cmd_rec *cmd) {
config_rec *c = NULL;
char *ciphersuite = NULL;
+ SSL_CTX *ctx;
CHECK_ARGS(cmd, 1);
CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);
@@ -11984,8 +11985,26 @@ MODRET set_tlsciphersuite(cmd_rec *cmd) {
c = add_config_param(cmd->argv[0], 1, NULL);
/* Make sure that EXPORT ciphers cannot be used, per Bug#4163. */
- c->argv[0] = pstrcat(c->pool, "!EXPORT:", ciphersuite, NULL);
+ ciphersuite = pstrcat(c->pool, "!EXPORT:", ciphersuite, NULL);
+
+ /* Check that our construct ciphersuite is acceptable. */
+ ctx = SSL_CTX_new(SSLv23_server_method());
+ if (ctx != NULL) {
+ if (SSL_CTX_set_cipher_list(ctx, ciphersuite) != 1) {
+ /* Note: tls_get_errors() relies on session.pool, so temporarily set
+ * it to our temporary pool.
+ */
+ session.pool = cmd->tmp_pool;
+
+ CONF_ERROR(cmd, pstrcat(cmd->tmp_pool,
+ "unable to use configured TLSCipherSuite '", ciphersuite, "': ",
+ tls_get_errors(), NULL));
+ }
+
+ SSL_CTX_free(ctx);
+ }
+ c->argv[0] = ciphersuite;
return PR_HANDLED(cmd);
}
diff --git a/doc/contrib/mod_tls.html b/doc/contrib/mod_tls.html
index c1d3f2d..cc88946 100644
--- a/doc/contrib/mod_tls.html
+++ b/doc/contrib/mod_tls.html
@@ -295,7 +295,13 @@
<strong>Compatibility:</strong> 1.2.7rc1 and later
<p>
-Default cipher list is &quot;DEFAULT:!ADH:!EXPORT:!DES&quot;.
+Sets the list of SSL/TLS ciphersuites for use. Default cipher list is
+&quot;DEFAULT:!ADH:!EXPORT:!DES&quot;.
+
+<p>
+<b>Note</b> that <code>mod_tls</code> will automatically <i>prepend</i> the
+configured <em>cipher-list</em> with "!EXPORT", in order to <i>prevent</i> the
+use of the insecure "export grade" ciphers.
<p>
How to put together a <em>cipher list</em> parameter:
@@ -2215,6 +2221,19 @@
TLSDHParamFile /path/to/dh1024.pem
</pre>
+<p><a name="TLSNoCipherMatch">
+<font color=red>Question</font>: I tried to configure a specific ciphersuite
+using <code>TLSCipherSuite</code>, but ProFTPD fails on startup with this error:
+<pre>
+ fatal: TLSCipherSuite: unable to use configured TLSCipherSuite '!EXPORT:MYCIPHER':
+ (1) error:1410D0B9:SSL routines:SSL_CTX_set_cipher_list:no cipher match on line 16 of '/etc/proftpd/tls.conf'
+</pre>
+<font color=blue>Answer</font>: This error indicates that the version of OpenSSL
+does not recognize/support one of the ciphers that you configured in your
+<code>TLSCipherSuite</code> list. Unfortunately the OpenSSL error reporting
+does not pinpoint <i>which</i> is the offending ciphersuite; experimenting
+with your cipher list will reveal which ones are problematic.
+
<p>
<hr>
<h2><a name="Installation">Installation</a></h2>
diff --git a/tests/t/lib/ProFTPD/Tests/Modules/mod_tls.pm b/tests/t/lib/ProFTPD/Tests/Modules/mod_tls.pm
index f7cd171..226d47c 100644
--- a/tests/t/lib/ProFTPD/Tests/Modules/mod_tls.pm
+++ b/tests/t/lib/ProFTPD/Tests/Modules/mod_tls.pm
@@ -299,6 +299,11 @@ my $TESTS = {
test_class => [qw(bug forking)],
},
+ tls_config_tlsciphersuite_bad_cipher => {
+ order => ++$order,
+ test_class => [qw(forking)],
+ },
+
tls_session_cache_off_bug3869 => {
order => ++$order,
test_class => [qw(bug forking)],
@@ -8983,6 +8988,51 @@ sub tls_config_tlsdhparamfile_bug3868 {
unlink($log_file);
}
+sub tls_config_tlsciphersuite_bad_cipher {
+ my $self = shift;
+ my $tmpdir = $self->{tmpdir};
+ my $setup = test_setup($tmpdir, 'tls');
+
+ my $cert_file = File::Spec->rel2abs('t/etc/modules/mod_tls/server-cert.pem');
+ my $ca_file = File::Spec->rel2abs('t/etc/modules/mod_tls/ca-cert.pem');
+
+ my $config = {
+ PidFile => $setup->{pid_file},
+ ScoreboardFile => $setup->{scoreboard_file},
+ SystemLog => $setup->{log_file},
+
+ IfModules => {
+ 'mod_delay.c' => {
+ DelayEngine => 'off',
+ },
+
+ 'mod_tls.c' => {
+ TLSEngine => 'on',
+ TLSLog => $setup->{log_file},
+ TLSRSACertificateFile => $cert_file,
+ TLSCACertificateFile => $ca_file,
+ TLSCipherSuite => 'FOOBAR',
+ },
+ },
+ };
+
+ my ($port, $config_user, $config_group) = config_write($setup->{config_file},
+ $config);
+
+ my $ex;
+
+ # This should silently fail.
+ server_start($setup->{config_file});
+
+ # This is where we detect the actual problem.
+ eval { server_stop($setup->{pid_file}) };
+ unless ($@) {
+ $ex = "Server start with bad config unexpectedly";
+ }
+
+ test_cleanup($setup->{log_file}, $ex);
+}
+
sub tls_session_cache_off_bug3869 {
my $self = shift;
my $tmpdir = $self->{tmpdir};

View File

@ -1,23 +0,0 @@
From ad786eaa8a232795470dbeab2380dc8d8ac803af Mon Sep 17 00:00:00 2001
From: TJ Saunders <tj@castaglia.org>
Date: Fri, 27 Oct 2017 09:28:19 -0700
Subject: [PATCH] Merge pull request #617 from pghmcfc/systemd-network-online
systemd: use network-online.target
---
contrib/dist/rpm/proftpd.service | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/contrib/dist/rpm/proftpd.service b/contrib/dist/rpm/proftpd.service
index 8a4df33c9..6c81db398 100644
--- a/contrib/dist/rpm/proftpd.service
+++ b/contrib/dist/rpm/proftpd.service
@@ -1,6 +1,7 @@
[Unit]
Description = ProFTPD FTP Server
-After = network.target nss-lookup.target local-fs.target remote-fs.target
+Wants=network-online.target
+After=network-online.target nss-lookup.target local-fs.target remote-fs.target
[Service]
Type = simple

View File

@ -1,25 +0,0 @@
From 84549ece3a839161794deee1721fc0cf9bf9eb9c Mon Sep 17 00:00:00 2001
From: Paul Howarth <paul@city-fan.org>
Date: Mon, 8 May 2017 10:16:32 +0100
Subject: [PATCH] Use absolute pathnames for executables in systemd unit files
Otherwise, systemd complains about them and ignores the commands.
---
contrib/dist/rpm/proftpd.service | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/contrib/dist/rpm/proftpd.service b/contrib/dist/rpm/proftpd.service
index c2fd401..07802ca 100644
--- a/contrib/dist/rpm/proftpd.service
+++ b/contrib/dist/rpm/proftpd.service
@@ -8,8 +8,8 @@ PIDFile = /run/proftpd/proftpd.pid
Environment = PROFTPD_OPTIONS=
EnvironmentFile = -/etc/sysconfig/proftpd
ExecStart = /usr/sbin/proftpd $PROFTPD_OPTIONS
-ExecStartPost = touch /var/lock/subsys/proftpd
-ExecStopPost = rm -f /var/lock/subsys/proftpd
+ExecStartPost = /usr/bin/touch /var/lock/subsys/proftpd
+ExecStopPost = /bin/rm -f /var/lock/subsys/proftpd
ExecReload = /bin/kill -HUP $MAINPID
[Install]

70
anonftp.conf Normal file
View File

@ -0,0 +1,70 @@
# A basic anonymous configuration, with an upload directory
# Enable this with PROFTPD_OPTIONS=-DANONYMOUS_FTP in /etc/sysconfig/proftpd
<Anonymous ~ftp>
User ftp
Group ftp
AccessGrantMsg "Anonymous login ok, restrictions apply."
# We want clients to be able to login with "anonymous" as well as "ftp"
UserAlias anonymous ftp
# Limit the maximum number of anonymous logins
MaxClients 10 "Sorry, max %m users -- try again later"
# Put the user into /pub right after login
#DefaultChdir /pub
# We want 'welcome.msg' displayed at login, '.message' displayed in
# each newly chdired directory and tell users to read README* files.
DisplayLogin /welcome.msg
DisplayChdir .message
DisplayReadme README*
# Cosmetic option to make all files appear to be owned by user "ftp"
DirFakeUser on ftp
DirFakeGroup on ftp
# Limit WRITE everywhere in the anonymous chroot
<Limit WRITE SITE_CHMOD>
DenyAll
</Limit>
# An upload directory that allows storing files but not retrieving
# or creating directories.
#
# Directory specification is slightly different if mod_vroot is in
# use: see http://sourceforge.net/p/proftp/mailman/message/31728570/
# https://bugzilla.redhat.com/show_bug.cgi?id=1045922
<IfModule mod_vroot.c>
<Directory /uploads/*>
AllowOverwrite no
<Limit READ>
DenyAll
</Limit>
<Limit STOR>
AllowAll
</Limit>
</Directory>
</IfModule>
<IfModule !mod_vroot.c>
<Directory uploads/*>
AllowOverwrite no
<Limit READ>
DenyAll
</Limit>
<Limit STOR>
AllowAll
</Limit>
</Directory>
</IfModule>
# Don't write anonymous accesses to the system wtmp file (good idea!)
WtmpLog off
# Logging for the anonymous transfers
ExtendedLog /var/log/proftpd/access.log WRITE,READ default
ExtendedLog /var/log/proftpd/auth.log AUTH auth
</Anonymous>

View File

@ -1,97 +0,0 @@
From c3e5d75f9c8a60af42646319fcca832d5f1a55d4 Mon Sep 17 00:00:00 2001
From: TJ Saunders <tj@castaglia.org>
Date: Sun, 21 May 2017 13:44:23 -0700
Subject: [PATCH] Merge pull request #513 from pghmcfc/similars
Fix pr_str_get_similars
---
src/str.c | 4 ++--
tests/api/str.c | 36 +++++++++++++++++++-----------------
2 files changed, 21 insertions(+), 19 deletions(-)
diff --git a/src/str.c b/src/str.c
index eeed096ef..0a59f2379 100644
--- a/src/str.c
+++ b/src/str.c
@@ -725,11 +725,11 @@ static int distance_cmp(const void *a, const void *b) {
const char *s1, *s2;
int distance1, distance2;
- cand1 = a;
+ cand1 = * (const struct candidate **) a;
s1 = cand1->s;
distance1 = cand1->distance;
- cand2 = b;
+ cand2 = * (const struct candidate **) b;
s2 = cand2->s;
distance2 = cand2->distance;
diff --git a/tests/api/str.c b/tests/api/str.c
index 7c6e11000..9dce95820 100644
--- a/tests/api/str.c
+++ b/tests/api/str.c
@@ -1469,25 +1469,23 @@ START_TEST (similars_test) {
mark_point();
similars = (const char **) res->elts;
- /* Note: We see different results here due to (I think) different
- * qsort(3) implementations.
+ /*
+ * Note: expected distances are as follows:
+ *
+ * Candidate Case-Sensitive Case-Insensitive
+ * fools 0 0
+ * odd 5 5
+ * bar 5 5
+ * FOO 5 0
*/
- expected = "FOO";
- if (strcmp(similars[0], expected) != 0) {
- expected = "fools";
- }
+ expected = "fools";
fail_unless(strcmp(similars[0], expected) == 0,
"Expected similar '%s', got '%s'", expected, similars[0]);
- expected = "fools";
- if (strcmp(similars[1], expected) != 0) {
- expected = "FOO";
- }
-
- fail_unless(strcmp(similars[1], expected) == 0,
- "Expected similar '%s', got '%s'", expected, similars[1]);
+ fail_unless(strcmp(similars[1], expected) != 0,
+ "Unexpectedly got similar '%s'", similars[1]);
mark_point();
res = pr_str_get_similars(p, s, candidates, 0, PR_STR_FL_IGNORE_CASE);
@@ -1499,18 +1497,22 @@ START_TEST (similars_test) {
mark_point();
similars = (const char **) res->elts;
+ /*
+ * similars[0] and similars[1] should be "FOO" and "fools", but
+ * not necessarily in that order
+ */
expected = "FOO";
if (strcmp(similars[0], expected) != 0) {
- expected = "fools";
+ expected = similars[0];
+ similars[0] = similars[1];
+ similars[1] = expected;
+ expected = "FOO";
}
fail_unless(strcmp(similars[0], expected) == 0,
"Expected similar '%s', got '%s'", expected, similars[0]);
expected = "fools";
- if (strcmp(similars[1], expected) != 0) {
- expected = "FOO";
- }
fail_unless(strcmp(similars[1], expected) == 0,
"Expected similar '%s', got '%s'", expected, similars[1]);

View File

@ -1,31 +0,0 @@
From fa378a8f2bc1b24ab93c157495960080aa788299 Mon Sep 17 00:00:00 2001
From: TJ Saunders <tj@castaglia.org>
Date: Wed, 8 Aug 2018 11:15:21 -0700
Subject: [PATCH] Bug#4356: Fix infinite loop by actually iterating properly
for the next configuration record. Oops.
---
contrib/mod_sftp/mod_sftp.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/contrib/mod_sftp/mod_sftp.c b/contrib/mod_sftp/mod_sftp.c
index b7fdfa541..655b12af1 100644
--- a/contrib/mod_sftp/mod_sftp.c
+++ b/contrib/mod_sftp/mod_sftp.c
@@ -1,6 +1,6 @@
/*
* ProFTPD - mod_sftp
- * Copyright (c) 2008-2017 TJ Saunders
+ * Copyright (c) 2008-2018 TJ Saunders
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1211,6 +1211,8 @@ MODRET set_sftphostkey(cmd_rec *cmd) {
insecure_hostkey_perms = TRUE;
break;
}
+
+ c = find_config_next(c, c->next, CONF_PARAM, "SFTPOptions", FALSE);
}
if (insecure_hostkey_perms) {

17
mod_ban.conf Normal file
View File

@ -0,0 +1,17 @@
# Dynamic ban lists (http://www.proftpd.org/docs/contrib/mod_ban.html)
<IfModule mod_ban.c>
BanEngine on
BanLog /var/log/proftpd/ban.log
BanTable @RUNDIR@/proftpd/ban.tab
# If the same client reaches the MaxLoginAttempts limit 2 times
# within 10 minutes, automatically add a ban for that client that
# will expire after one hour.
BanOnEvent MaxLoginAttempts 2/00:10:00 01:00:00
# Inform the user that it's not worth persisting
BanMessage "Host %a has been banned"
# Allow the FTP admin to manually add/remove bans
BanControlsACLs all allow user ftpadm
</IfModule>

8
mod_qos.conf Normal file
View File

@ -0,0 +1,8 @@
# Set networking-specific "Quality of Service" (QoS) bits on the packets used
# by the server (http://www.proftpd.org/docs/contrib/mod_qos.html)
<IfModule mod_qos.c>
# RFC791 TOS parameter compatibility
QoSOptions dataqos throughput ctrlqos lowdelay
# For a DSCP environment (may require tweaking)
#QoSOptions dataqos CS2 ctrlqos AF41
</IfModule>

15
mod_tls.conf Normal file
View File

@ -0,0 +1,15 @@
# TLS (http://www.castaglia.org/proftpd/modules/mod_tls.html)
<IfModule mod_tls.c>
TLSEngine on
TLSRequired off
TLSCertificateChainFile /etc/pki/tls/certs/proftpd-chain.pem
TLSRSACertificateFile /etc/pki/tls/certs/proftpd-cert.pem
TLSRSACertificateKeyFile /etc/pki/tls/private/proftpd-key.pem
TLSCipherSuite PROFILE=SYSTEM
# Relax the requirement that the SSL session be re-used for data transfers
TLSOptions NoSessionReuseRequired
TLSLog /var/log/proftpd/tls.log
<IfModule mod_tls_shmcache.c>
TLSSessionCache shm:/file=@RUNDIR@/proftpd/sesscache
</IfModule>
</IfModule>

180
modules.conf Normal file
View File

@ -0,0 +1,180 @@
# Dynamic Shared Object (DSO) loading
# See README.DSO and howto/DSO.html for more details
# Allow only user root to load and unload modules, but allow everyone
# to see which modules have been loaded
# (http://www.proftpd.org/docs/modules/mod_dso.html#ModuleControlsACLs)
ModuleControlsACLs insmod,rmmod allow user root
ModuleControlsACLs lsmod allow user *
#
# General database support (http://www.proftpd.org/docs/contrib/mod_sql.html)
# Note that this module is required if you use any of the other mod_sql_*
# modules
# LoadModule mod_sql.c
#
# Support for base-64 or hex encoded MD5 and SHA1 passwords from SQL tables
# (contrib/mod_sql_passwd.html)
# LoadModule mod_sql_passwd.c
#
# Mysql support (requires proftpd-mysql package)
# (http://www.proftpd.org/docs/contrib/mod_sql.html)
# LoadModule mod_sql_mysql.c
#
# Postgresql support (requires proftpd-postgresql package)
# (http://www.proftpd.org/docs/contrib/mod_sql.html)
# LoadModule mod_sql_postgres.c
#
# SQLite support (requires proftpd-sqlite package)
# (http://www.proftpd.org/docs/contrib/mod_sql.html,
# http://www.proftpd.org/docs/contrib/mod_sql_sqlite.html)
# LoadModule mod_sql_sqlite.c
#
# Quota support (http://www.proftpd.org/docs/contrib/mod_quotatab.html)
# LoadModule mod_quotatab.c
#
# File-specific "driver" for storing quota table information in files
# (http://www.proftpd.org/docs/contrib/mod_quotatab_file.html)
# LoadModule mod_quotatab_file.c
#
# SQL database "driver" for storing quota table information in SQL tables
# (http://www.proftpd.org/docs/contrib/mod_quotatab_sql.html)
# LoadModule mod_quotatab_sql.c
#
# LDAP support (requires proftpd-ldap package)
# (http://www.proftpd.org/docs/directives/linked/config_ref_mod_ldap.html)
# LoadModule mod_ldap.c
#
# LDAP quota support (requires proftpd-ldap package)
# (http://www.proftpd.org/docs/contrib/mod_quotatab_ldap.html)
# LoadModule mod_quotatab_ldap.c
#
# Support for authenticating users using the RADIUS protocol
# (http://www.proftpd.org/docs/contrib/mod_radius.html)
# LoadModule mod_radius.c
#
# Retrieve quota limit table information from a RADIUS server
# (http://www.proftpd.org/docs/contrib/mod_quotatab_radius.html)
# LoadModule mod_quotatab_radius.c
#
# SITE CPFR and SITE CPTO commands (analogous to RNFR and RNTO), which can be
# used to copy files/directories from one place to another on the server
# without having to transfer the data to the client and back
# (http://www.castaglia.org/proftpd/modules/mod_copy.html)
# LoadModule mod_copy.c
#
# Administrative control actions for the ftpdctl program
# (http://www.proftpd.org/docs/contrib/mod_ctrls_admin.html)
LoadModule mod_ctrls_admin.c
#
# Support for MODE Z commands, which allows FTP clients and servers to
# compress data for transfer
# (http://www.castaglia.org/proftpd/modules/mod_deflate.html)
# LoadModule mod_deflate.c
#
# Execute external programs or scripts at various points in the process
# of handling FTP commands
# (http://www.castaglia.org/proftpd/modules/mod_exec.html)
# LoadModule mod_exec.c
#
# Support for POSIX ACLs
# (http://www.proftpd.org/docs/modules/mod_facl.html)
# LoadModule mod_facl.c
#
# Support for using the GeoIP library to look up geographical information on
# the connecting client and using that to set access controls for the server
# (http://www.castaglia.org/proftpd/modules/mod_geoip.html)
# LoadModule mod_geoip.c
#
# Allow for version-specific configuration sections of the proftpd config file,
# useful for using the same proftpd config across multiple servers where
# different proftpd versions may be in use
# (http://www.castaglia.org/proftpd/modules/mod_ifversion.html)
# LoadModule mod_ifversion.c
#
# Configure server availability based on system load
# (http://www.proftpd.org/docs/contrib/mod_load.html)
# LoadModule mod_load.c
#
# Limit downloads to a multiple of upload volume (see README.ratio)
# LoadModule mod_ratio.c
#
# Rewrite FTP commands sent by clients on-the-fly,
# using regular expression matching and substitution
# (http://www.proftpd.org/docs/contrib/mod_rewrite.html)
# LoadModule mod_rewrite.c
#
# Support for the SSH2, SFTP, and SCP protocols, for secure file transfer over
# an SSH2 connection (http://www.castaglia.org/proftpd/modules/mod_sftp.html)
# LoadModule mod_sftp.c
#
# Use PAM to provide a 'keyboard-interactive' SSH2 authentication method for
# mod_sftp (http://www.castaglia.org/proftpd/modules/mod_sftp_pam.html)
# LoadModule mod_sftp_pam.c
#
# Use SQL (via mod_sql) for looking up authorized SSH2 public keys for user
# and host based authentication
# (http://www.castaglia.org/proftpd/modules/mod_sftp_sql.html)
# LoadModule mod_sftp_sql.c
#
# Provide data transfer rate "shaping" across the entire server
# (http://www.castaglia.org/proftpd/modules/mod_shaper.html)
# LoadModule mod_shaper.c
#
# Support for miscellaneous SITE commands such as SITE MKDIR, SITE SYMLINK,
# and SITE UTIME (http://www.proftpd.org/docs/contrib/mod_site_misc.html)
# LoadModule mod_site_misc.c
#
# Provide an external SSL session cache using shared memory
# (contrib/mod_tls_shmcache.html)
# LoadModule mod_tls_shmcache.c
#
# Provide a memcached-based implementation of an external SSL session cache
# (contrib/mod_tls_memcache.html)
# LoadModule mod_tls_memcache.c
#
# Use the /etc/hosts.allow and /etc/hosts.deny files, or other allow/deny
# files, for IP-based access control
# (http://www.proftpd.org/docs/contrib/mod_wrap.html)
# LoadModule mod_wrap.c
#
# Use the /etc/hosts.allow and /etc/hosts.deny files, or other allow/deny
# files, as well as SQL-based access rules, for IP-based access control
# (http://www.proftpd.org/docs/contrib/mod_wrap2.html)
# LoadModule mod_wrap2.c
#
# Support module for mod_wrap2 that handles access rules stored in specially
# formatted files on disk
# (http://www.proftpd.org/docs/contrib/mod_wrap2_file.html)
# LoadModule mod_wrap2_file.c
#
# Support module for mod_wrap2 that handles access rules stored in SQL
# database tables (http://www.proftpd.org/docs/contrib/mod_wrap2_sql.html)
# LoadModule mod_wrap2_sql.c
#
# Implement a virtual chroot capability that does not require root privileges
# (http://www.castaglia.org/proftpd/modules/mod_vroot.html)
# Using this module rather than the kernel's chroot() system call works
# around issues with PAM and chroot (http://bugzilla.redhat.com/506735)
LoadModule mod_vroot.c
# Dynamic ban lists (http://www.proftpd.org/docs/contrib/mod_ban.html)
# Enable this with PROFTPD_OPTIONS=-DDYNAMIC_BAN_LISTS in /etc/sysconfig/proftpd
<IfDefine DYNAMIC_BAN_LISTS>
LoadModule mod_ban.c
</IfDefine>
# Set networking-specific "Quality of Service" (QoS) bits on the packets used
# by the server (contrib/mod_qos.html)
<IfDefine QOS>
LoadModule mod_qos.c
</IfDefine>
# Provide a flexible way of specifying that certain configuration directives
# only apply to certain sessions, based on credentials such as connection
# class, user, or group membership
# (http://www.proftpd.org/docs/contrib/mod_ifsession.html)
# Note that mod_ifsession must be the last loaded module, otherwise the
# per-user/group/class functionality will not work as you expect
# LoadModule mod_ifsession.c

View File

@ -1,6 +1,6 @@
--- proftpd-1.3.4rc1/tests/tests.pl 2010-12-15 00:57:04.000000000 +0000 --- proftpd-1.3.4rc1/tests/tests.pl 2010-12-15 00:57:04.000000000 +0000
+++ proftpd-1.3.4rc1/tests/tests.pl 2011-01-11 09:22:57.746669659 +0000 +++ proftpd-1.3.4rc1/tests/tests.pl 2011-01-11 09:22:57.746669659 +0000
@@ -283,6 +283,11 @@ @@ -478,6 +478,11 @@
test_class => [qw(mod_unique_id)], test_class => [qw(mod_unique_id)],
}, },

View File

@ -1,15 +0,0 @@
--- proftpd-1.3.6/tests/api/fsio.c
+++ proftpd-1.3.6/tests/api/fsio.c
@@ -26,6 +26,12 @@
#include "tests.h"
+#ifdef PR_USE_XATTR
+#ifndef ENOATTR
+# define ENOATTR ENODATA
+#endif
+#endif
+
static pool *p = NULL;
static char *fsio_cwd = NULL;

View File

@ -1,187 +0,0 @@
From 49ef73f7193242eac07de27c2e853d9e805162ec Mon Sep 17 00:00:00 2001
From: Paul Howarth <paul@city-fan.org>
Date: Wed, 3 May 2017 11:57:23 +0100
Subject: [PATCH] Add --enable-tests=nonetwork option
This disables API tests that involve resolving/connecting to external
network services such as Google, which may not be possible in some
build environments.
Tested using systemd-nspawn --private-network
---
config.h.in | 3 +++
configure.in | 5 ++++-
tests/api/inet.c | 6 ++++++
tests/api/netaddr.c | 6 ++++++
4 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/config.h.in b/config.h.in
index a38734a..229c9db 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1068,6 +1068,9 @@
/* Define if ncursesw support, if available, should be used. */
#undef PR_USE_NCURSESW
+/* Define if non-local network tests are enabled. */
+#undef PR_USE_NETWORK_TESTS
+
/* Define if using nonblocking open of log files. */
#undef PR_USE_NONBLOCKING_LOG_OPEN
diff --git a/configure.in b/configure.in
index 1e39c37..dba39ba 100644
--- a/configure.in
+++ b/configure.in
@@ -985,7 +985,7 @@ AC_ARG_ENABLE(tests,
[--enable-tests],
[enable unit tests (default=no)])
],
- [ if test x"$enableval" = x"yes" ; then
+ [ if test x"$enableval" = x"yes" || test x"$enableval" = x"nonetwork" ; then
AC_CHECK_HEADERS(check.h)
AC_CHECK_LIB(check, tcase_create,
@@ -997,6 +997,9 @@ AC_ARG_ENABLE(tests,
AC_MSG_ERROR([libcheck support, required for tests, not present -- aborting])
]
)
+ if test x"$enableval" != x"nonetwork" ; then
+ AC_DEFINE(PR_USE_NETWORK_TESTS, 1, [Define if non-local network tests are enabled.])
+ fi
fi
])
diff -up a/configure b/configure
--- a/configure
+++ b/configure
@@ -20423,7 +20423,7 @@ fi
ENABLE_TESTS="\"\""
# Check whether --enable-tests was given.
if test "${enable_tests+set}" = set; then
- enableval=$enable_tests; if test x"$enableval" = x"yes" ; then
+ enableval=$enable_tests; if test x"$enableval" = x"yes" || test x"$enableval" = x"nonetwork" ; then
for ac_header in check.h
do
@@ -20648,6 +20648,13 @@ echo "$as_me: error: libcheck support, r
fi
+ if test x"$enableval" != x"nonetwork" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define PR_USE_NETWORK_TESTS 1
+_ACEOF
+
+ fi
fi
fi
diff --git a/tests/api/inet.c b/tests/api/inet.c
index 03c4781..c111629 100644
--- a/tests/api/inet.c
+++ b/tests/api/inet.c
@@ -522,6 +522,7 @@ START_TEST (inet_connect_ipv4_test) {
fail_unless(errno == ECONNREFUSED, "Expected ECONNREFUSED (%d), got %s (%d)",
ECONNREFUSED, strerror(errno), errno);
+#if defined(PR_USE_NETWORK_TESTS)
/* Try connecting to Google's DNS server. */
addr = pr_netaddr_get_addr(p, "8.8.8.8", NULL);
@@ -551,6 +552,7 @@ START_TEST (inet_connect_ipv4_test) {
fail_unless(errno == EISCONN, "Expected EISCONN (%d), got %s (%d)",
EISCONN, strerror(errno), errno);
pr_inet_close(p, conn);
+#endif
}
END_TEST
@@ -579,6 +581,7 @@ START_TEST (inet_connect_ipv6_test) {
"Expected ECONNREFUSED (%d), ENETUNREACH (%d), or EADDRNOTAVAIL (%d), got %s (%d)",
ECONNREFUSED, ENETUNREACH, EADDRNOTAVAIL, strerror(errno), errno);
+#if defined(PR_USE_NETWORK_TESTS)
/* Try connecting to Google's DNS server. */
addr = pr_netaddr_get_addr(p, "2001:4860:4860::8888", NULL);
@@ -614,6 +617,7 @@ START_TEST (inet_connect_ipv6_test) {
fail_unless(errno == EISCONN || errno == EHOSTUNREACH || errno == ENETUNREACH || errno == EADDRNOTAVAIL,
"Expected EISCONN (%d) or EHOSTUNREACH (%d) or ENETUNREACH (%d) or EADDRNOTAVAIL (%d), got %s (%d)", EISCONN, EHOSTUNREACH, ENETUNREACH, EADDRNOTAVAIL, strerror(errno), errno);
pr_inet_close(p, conn);
+#endif
pr_inet_set_default_family(p, AF_INET);
@@ -649,6 +653,7 @@ START_TEST (inet_connect_nowait_test) {
res = pr_inet_connect_nowait(p, conn, addr, 180);
fail_unless(res != -1, "Connected to 127.0.0.1#180 unexpectedly");
+#if defined(PR_USE_NETWORK_TESTS)
/* Try connecting to Google's DNS server. */
addr = pr_netaddr_get_addr(p, "8.8.8.8", NULL);
@@ -664,6 +669,7 @@ START_TEST (inet_connect_nowait_test) {
}
pr_inet_close(p, conn);
+#endif
/* Restore the default family to AF_INET, for other tests. */
pr_inet_set_default_family(p, AF_INET);
diff --git a/tests/api/netaddr.c b/tests/api/netaddr.c
index 80d3327..124dc39 100644
--- a/tests/api/netaddr.c
+++ b/tests/api/netaddr.c
@@ -146,6 +146,7 @@ START_TEST (netaddr_get_addr_test) {
fail_unless(res->na_family == AF_INET, "Expected family %d, got %d",
AF_INET, res->na_family);
+#if defined(PR_USE_NETWORK_TESTS)
/* Google: the Dial Tone of the Internet. */
name = "www.google.com";
@@ -161,6 +162,7 @@ START_TEST (netaddr_get_addr_test) {
strerror(errno));
fail_unless(res->na_family == AF_INET, "Expected family %d, got %d",
AF_INET, res->na_family);
+#endif
name = "127.0.0.1";
@@ -903,6 +905,7 @@ START_TEST (netaddr_get_dnsstr_list_test) {
pr_netaddr_clear_cache();
+#if defined(PR_USE_NETWORK_TESTS)
addr = pr_netaddr_get_addr(p, "www.google.com", &addrs);
fail_unless(addr != NULL, "Failed to resolve 'www.google.com': %s",
strerror(errno));
@@ -921,6 +924,7 @@ START_TEST (netaddr_get_dnsstr_list_test) {
/* Ideally we would check that res->nelts > 0, BUT this turns out to
* a fragile test condition, dependent on DNS vagaries.
*/
+#endif
pr_netaddr_set_reverse_dns(reverse_dns);
}
@@ -1082,6 +1086,7 @@ START_TEST (netaddr_is_loopback_test) {
fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
strerror(errno), errno);
+#if defined(PR_USE_NETWORK_TESTS)
name = "www.google.com";
addr = pr_netaddr_get_addr(p, name, NULL);
fail_unless(addr != NULL, "Failed to resolve '%s': %s", name,
@@ -1089,6 +1094,7 @@ START_TEST (netaddr_is_loopback_test) {
res = pr_netaddr_is_loopback(addr);
fail_unless(res == FALSE, "Expected FALSE, got %d", res);
+#endif
name = "127.0.0.1";
addr = pr_netaddr_get_addr(p, name, NULL);
--
2.9.3

View File

@ -0,0 +1,14 @@
--- modules.conf
+++ modules.conf
@@ -82,11 +82,6 @@ LoadModule mod_ctrls_admin.c
# (http://www.proftpd.org/docs/modules/mod_facl.html)
# LoadModule mod_facl.c
#
-# Support for using the GeoIP library to look up geographical information on
-# the connecting client and using that to set access controls for the server
-# (http://www.castaglia.org/proftpd/modules/mod_geoip.html)
-# LoadModule mod_geoip.c
-#
# Allow for version-specific configuration sections of the proftpd config file,
# useful for using the same proftpd config across multiple servers where
# different proftpd versions may be in use

View File

@ -0,0 +1,14 @@
--- modules.conf
+++ modules.conf
@@ -135,11 +135,6 @@ LoadModule mod_ctrls_admin.c
# LoadModule mod_tls_shmcache.c
#
# Use the /etc/hosts.allow and /etc/hosts.deny files, or other allow/deny
-# files, for IP-based access control
-# (http://www.proftpd.org/docs/contrib/mod_wrap.html)
-# LoadModule mod_wrap.c
-#
-# Use the /etc/hosts.allow and /etc/hosts.deny files, or other allow/deny
# files, as well as SQL-based access rules, for IP-based access control
# (http://www.proftpd.org/docs/contrib/mod_wrap2.html)
# LoadModule mod_wrap2.c

View File

@ -4,7 +4,7 @@
-#!/usr/bin/env perl -#!/usr/bin/env perl
+#!/usr/bin/perl +#!/usr/bin/perl
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Copyright (C) 2000-2015 TJ Saunders <tj@castaglia.org> # Copyright (C) 2000-2020 TJ Saunders <tj@castaglia.org>
# #
--- contrib/ftpmail --- contrib/ftpmail
+++ contrib/ftpmail +++ contrib/ftpmail
@ -12,7 +12,7 @@
-#!/usr/bin/env perl -#!/usr/bin/env perl
+#!/usr/bin/perl +#!/usr/bin/perl
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Copyright (C) 2008-2013 TJ Saunders <tj@castaglia.org> # Copyright (C) 2008-2017 TJ Saunders <tj@castaglia.org>
# #
--- contrib/ftpquota --- contrib/ftpquota
+++ contrib/ftpquota +++ contrib/ftpquota

View File

@ -0,0 +1,25 @@
From 27d632208163a73a0501e595fcdef0302cb44d8c Mon Sep 17 00:00:00 2001
From: eaglegai <eaglegai@163.com>
Date: Tue, 1 Jun 2021 17:21:55 +0800
Subject: [PATCH] proftpd 1.3.7a Adjusting unit test timeouts for netacl
---
tests/api/netacl.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tests/api/netacl.c b/tests/api/netacl.c
index c4da486..86b628d 100644
--- a/tests/api/netacl.c
+++ b/tests/api/netacl.c
@@ -894,6 +894,8 @@ Suite *tests_get_netacl_suite(void) {
tcase_add_test(testcase, netacl_match_test);
tcase_add_test(testcase, netacl_get_negated_test);
+ tcase_set_timeout(testcase, 60);
+
suite_add_tcase(suite, testcase);
return suite;
}
--
1.8.3.1

View File

@ -0,0 +1,24 @@
From ca74554f6f30ffea6842f375204736fd6bde78f4 Mon Sep 17 00:00:00 2001
From: TJ Saunders <tj@castaglia.org>
Date: Sat, 20 Mar 2021 09:53:11 -0700
Subject: [PATCH] Issue #1201: Adjusting unit test timeouts for the GitHub
Actions environment.
---
tests/api/netaddr.c | 3 +++
1 files changed, 3 insertions(+)
diff --git a/tests/api/netaddr.c b/tests/api/netaddr.c
index 6144c70695..60dbb29319 100644
--- a/tests/api/netaddr.c
+++ b/tests/api/netaddr.c
@@ -1464,6 +1464,9 @@ Suite *tests_get_netaddr_suite(void) {
tcase_add_test(testcase, netaddr_disable_ipv6_test);
tcase_add_test(testcase, netaddr_enable_ipv6_test);
+ /* Some of the DNS-related tests may take a little longer. */
+ tcase_set_timeout(testcase, 60);
+
suite_add_tcase(suite, testcase);
return suite;
}

View File

@ -0,0 +1,120 @@
--- tests/api/env.c
+++ tests/api/env.c
@@ -61,11 +61,11 @@ START_TEST (env_get_test) {
pr_env_unset(p, key);
res = pr_env_get(p, key);
- fail_unless(res == NULL);
+ fail_unless(res == NULL, "Unexpectedly found foo in environment");
/* XXX PATH should always be set in the environment, right? */
res = pr_env_get(p, "PATH");
- fail_unless(res != NULL);
+ fail_unless(res != NULL, "Failed to find PATH in environment");
#else
res = pr_env_get(p, key);
--- tests/api/sets.c
+++ tests/api/sets.c
@@ -97,20 +97,20 @@ START_TEST (set_create_test) {
fail_unless(errno == EPERM, "Failed to set errno to EPERM");
res = xaset_create(p, NULL);
- fail_unless(res != NULL);
+ fail_unless(res != NULL, "Failed with valid pool and NULL compare item");
fail_unless(res->pool == p, "Expected %p, got %p", p, res->pool);
permanent_pool = make_sub_pool(p);
res = xaset_create(NULL, NULL);
- fail_unless(res != NULL);
+ fail_unless(res != NULL, "Failed to handle null arguments");
fail_unless(res->pool == permanent_pool, "Expected %p, got %p",
permanent_pool, res->pool);
fail_unless(res->xas_compare == NULL, "Expected NULL, got %p",
res->xas_compare);
res = xaset_create(p, (XASET_COMPARE) item_cmp);
- fail_unless(res != NULL);
+ fail_unless(res != NULL, "Failed with valid pool and compare items");
fail_unless(res->pool == p, "Expected %p, got %p", p, res->pool);
fail_unless(res->xas_compare == (XASET_COMPARE) item_cmp,
"Expected %p, got %p", item_cmp, res->xas_compare);
@@ -355,12 +355,12 @@ START_TEST (set_remove_test) {
fail_unless(res == 0, "Failed to add item2");
member = (xasetmember_t *) item1;
- fail_unless(member->next == NULL);
- fail_unless(member->prev != NULL);
+ fail_unless(member->next == NULL, "Next pointer is not NULL");
+ fail_unless(member->prev != NULL, "Previous pointer is NULL");
member = (xasetmember_t *) item2;
- fail_unless(member->next != NULL);
- fail_unless(member->prev == NULL);
+ fail_unless(member->next != NULL, "Next pointer is NULL");
+ fail_unless(member->prev == NULL, "Previous pointer is not NULL");
member = set->xas_list;
fail_unless(member == (xasetmember_t *) item2,
@@ -371,8 +371,8 @@ START_TEST (set_remove_test) {
strerror(errno));
member = (xasetmember_t *) item2;
- fail_unless(member->next == NULL);
- fail_unless(member->prev == NULL);
+ fail_unless(member->next == NULL, "Next pointer is not NULL");
+ fail_unless(member->prev == NULL, "Previous pointer is not NULL");
member = set->xas_list;
fail_unless(member == (xasetmember_t *) item1,
@@ -383,8 +383,8 @@ START_TEST (set_remove_test) {
strerror(errno));
member = (xasetmember_t *) item1;
- fail_unless(member->next == NULL);
- fail_unless(member->prev == NULL);
+ fail_unless(member->next == NULL, "Next pointer is not NULL");
+ fail_unless(member->prev == NULL, "Previous pointer is not NULL");
member = set->xas_list;
fail_unless(member == NULL, "Expected list to be empty, got %p", member);
--- tests/api/str.c
+++ tests/api/str.c
@@ -1539,10 +1539,10 @@ START_TEST (uid2str_test) {
const char *res;
res = pr_uid2str(NULL, (uid_t) 1);
- fail_unless(strcmp(res, "1") == 0);
+ fail_unless(strcmp(res, "1") == 0, "Failed to handle uid of 1");
res = pr_uid2str(NULL, (uid_t) -1);
- fail_unless(strcmp(res, "-1") == 0);
+ fail_unless(strcmp(res, "-1") == 0, "Failed to handle uid of -1");
}
END_TEST
@@ -1550,10 +1550,10 @@ START_TEST (gid2str_test) {
const char *res;
res = pr_gid2str(NULL, (gid_t) 1);
- fail_unless(strcmp(res, "1") == 0);
+ fail_unless(strcmp(res, "1") == 0, "Failed to handle gid of 1");
res = pr_gid2str(NULL, (gid_t) -1);
- fail_unless(strcmp(res, "-1") == 0);
+ fail_unless(strcmp(res, "-1") == 0, "Failed to handle gid of -1");
}
END_TEST
--- tests/api/timers.c
+++ tests/api/timers.c
@@ -157,7 +157,7 @@ START_TEST (timer_remove_test) {
int res;
res = pr_timer_remove(0, NULL);
- fail_unless(res == 0);
+ fail_unless(res == 0, "Non-zero response for removal with timer ID 0");
res = pr_timer_add(1, 0, NULL, timers_test_cb, "test");
fail_unless(res == 0, "Failed to add timer (%d): %s", res, strerror(errno));

View File

@ -0,0 +1,84 @@
diff -ruNa proftpd-1.3.7a/tests/api/netacl.c proftpd-1.3.7a-fix/tests/api/netacl.c
--- proftpd-1.3.7a/tests/api/netacl.c 2020-07-22 01:25:51.000000000 +0800
+++ proftpd-1.3.7a-fix/tests/api/netacl.c 2021-01-13 14:44:00.679322360 +0800
@@ -773,8 +773,10 @@
res = pr_netacl_match(acl, addr);
if (getenv("TRAVIS") == NULL) {
- fail_unless(res == 1, "Failed to positively match ACL to addr: %s",
- strerror(errno));
+ if(strcmp(getenv("HOSTNAME"), "localhost") == 0 || strcmp(getenv("HOSTNAME"), "localhost.localdomain") == 0) {
+ fail_unless(res == 1, "Failed to positively match ACL to addr: %s",
+ strerror(errno));
+ }
}
if (!have_localdomain) {
@@ -790,8 +790,10 @@
res = pr_netacl_match(acl, addr);
if (getenv("TRAVIS") == NULL) {
- fail_unless(res == -1, "Failed to negatively match ACL to addr: %s",
- strerror(errno));
+ if(strcmp(getenv("HOSTNAME"), "localhost") == 0 || strcmp(getenv("HOSTNAME"), "localhost.localdomain") == 0) {
+ fail_unless(res == -1, "Failed to negatively match ACL to addr: %s",
+ strerror(errno));
+ }
}
acl_str = "!www.google.com";
@@ -816,8 +816,10 @@
res = pr_netacl_match(acl, addr);
if (getenv("TRAVIS") == NULL) {
- fail_unless(res == 1, "Failed to positively match ACL to addr: %s",
- strerror(errno));
+ if(strcmp(getenv("HOSTNAME"), "localhost") == 0 || strcmp(getenv("HOSTNAME"), "localhost.localdomain") == 0) {
+ fail_unless(res == 1, "Failed to positively match ACL to addr: %s",
+ strerror(errno));
+ }
}
if (!have_localdomain) {
@@ -833,8 +835,10 @@
res = pr_netacl_match(acl, addr);
if (getenv("TRAVIS") == NULL) {
- fail_unless(res == -1, "Failed to negatively match ACL to addr: %s",
- strerror(errno));
+ if(strcmp(getenv("HOSTNAME"), "localhost") == 0 || strcmp(getenv("HOSTNAME"), "localhost.localdomain") == 0) {
+ fail_unless(res == -1, "Failed to negatively match ACL to addr: %s",
+ strerror(errno));
+ }
}
acl_str = "!www.g*g.com";
diff -ruNa proftpd-1.3.7a/tests/api/netaddr.c proftpd-1.3.7a-fix/tests/api/netaddr.c
--- proftpd-1.3.7a/tests/api/netaddr.c 2021-01-13 14:30:47.467322360 +0800
+++ proftpd-1.3.7a-fix/tests/api/netaddr.c 2021-01-13 14:42:45.851322360 +0800
@@ -417,7 +417,9 @@
res = pr_netaddr_fnmatch(addr, "LOCAL*", flags);
if (getenv("TRAVIS") == NULL) {
/* This test is sensitive the environment. */
- fail_unless(res == TRUE, "Expected TRUE, got %d", res);
+ if(strcmp(getenv("HOSTNAME"), "localhost") == 0 || strcmp(getenv("HOSTNAME"), "localhost.localdomain") == 0) {
+ fail_unless(res == TRUE, "Expected TRUE, got %d", res);
+ }
}
flags = PR_NETADDR_MATCH_IP;
@@ -879,9 +881,11 @@
*/
if (getenv("TRAVIS") == NULL) {
/* This test is sensitive the environment. */
- fail_unless(strcmp(res, "localhost") == 0 ||
- strcmp(res, "localhost.localdomain") == 0,
- "Expected '%s', got '%s'", "localhost or localhost.localdomain", res);
+ if(strcmp(getenv("HOSTNAME"), "localhost") == 0 || strcmp(getenv("HOSTNAME"), "localhost.localdomain") == 0) {
+ fail_unless(strcmp(res, "localhost") == 0 ||
+ strcmp(res, "localhost.localdomain") == 0,
+ "Expected '%s', got '%s'", "localhost or localhost.localdomain", res);
+ }
}
}
END_TEST

View File

@ -0,0 +1,22 @@
--- tests/api/netaddr.c
+++ tests/api/netaddr.c
@@ -135,7 +135,8 @@ START_TEST (netaddr_get_addr_test) {
res = pr_netaddr_get_addr(p, name, NULL);
fail_unless(res == NULL, "Unexpected got address for '%s'", name);
- fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
+ fail_unless(errno == ENOENT || errno == EAGAIN,
+ "Expected ENOENT (%d) or EAGAIN (%d), got %s (%d)", ENOENT, EAGAIN,
strerror(errno), errno);
name = "localhost";
@@ -190,7 +191,8 @@ START_TEST (netaddr_get_addr_test) {
res = pr_netaddr_get_addr(p, name, NULL);
fail_unless(res == NULL, "Resolved '%s' unexpectedly", name);
- fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
+ fail_unless(errno == ENOENT || errno == EAGAIN,
+ "Expected ENOENT (%d) or EAGAIN (%d), got %s (%d)", ENOENT, EAGAIN,
strerror(errno), errno);
#if defined(PR_USE_IPV6)

View File

@ -0,0 +1,12 @@
--- proftpd.conf
+++ proftpd.conf
@@ -114,9 +114,6 @@ UseSendfile off
LogFormat default "%h %l %u %t \"%r\" %s %b"
LogFormat auth "%v [%P] %h %t \"%r\" %s"
-# Don't log hostname or timestamps because systemd will do that for us
-LogOptions -Timestamp -Hostname +RoleBasedProcessLabels
-
# Enable basic controls via ftpdctl
# (http://www.proftpd.org/docs/modules/mod_ctrls.html)
ControlsEngine on

View File

@ -66,6 +66,9 @@
# will not be able to read and/or write a file unless *all* of the ownership, # will not be able to read and/or write a file unless *all* of the ownership,
# permission and SELinux restrictions allow it. # permission and SELinux restrictions allow it.
# Load DSO modules as required
Include /etc/proftpd/modules.conf
# Server Config - config used for anything outside a <VirtualHost> or <Global> context # Server Config - config used for anything outside a <VirtualHost> or <Global> context
# See: http://www.proftpd.org/docs/howto/Vhost.html # See: http://www.proftpd.org/docs/howto/Vhost.html
@ -111,168 +114,8 @@ UseSendfile off
LogFormat default "%h %l %u %t \"%r\" %s %b" LogFormat default "%h %l %u %t \"%r\" %s %b"
LogFormat auth "%v [%P] %h %t \"%r\" %s" LogFormat auth "%v [%P] %h %t \"%r\" %s"
# Dynamic Shared Object (DSO) loading # Don't log hostname or timestamps because systemd will do that for us
# See README.DSO and howto/DSO.html for more details LogOptions -Timestamp -Hostname +RoleBasedProcessLabels
#
# General database support (http://www.proftpd.org/docs/contrib/mod_sql.html)
# LoadModule mod_sql.c
#
# Support for base-64 or hex encoded MD5 and SHA1 passwords from SQL tables
# (contrib/mod_sql_passwd.html)
# LoadModule mod_sql_passwd.c
#
# Mysql support (requires proftpd-mysql package)
# (http://www.proftpd.org/docs/contrib/mod_sql.html)
# LoadModule mod_sql_mysql.c
#
# Postgresql support (requires proftpd-postgresql package)
# (http://www.proftpd.org/docs/contrib/mod_sql.html)
# LoadModule mod_sql_postgres.c
#
# SQLite support (requires proftpd-sqlite package)
# (http://www.proftpd.org/docs/contrib/mod_sql.html,
# http://www.proftpd.org/docs/contrib/mod_sql_sqlite.html)
# LoadModule mod_sql_sqlite.c
#
# Quota support (http://www.proftpd.org/docs/contrib/mod_quotatab.html)
# LoadModule mod_quotatab.c
#
# File-specific "driver" for storing quota table information in files
# (http://www.proftpd.org/docs/contrib/mod_quotatab_file.html)
# LoadModule mod_quotatab_file.c
#
# SQL database "driver" for storing quota table information in SQL tables
# (http://www.proftpd.org/docs/contrib/mod_quotatab_sql.html)
# LoadModule mod_quotatab_sql.c
#
# LDAP support (requires proftpd-ldap package)
# (http://www.proftpd.org/docs/directives/linked/config_ref_mod_ldap.html)
# LoadModule mod_ldap.c
#
# LDAP quota support (requires proftpd-ldap package)
# (http://www.proftpd.org/docs/contrib/mod_quotatab_ldap.html)
# LoadModule mod_quotatab_ldap.c
#
# Support for authenticating users using the RADIUS protocol
# (http://www.proftpd.org/docs/contrib/mod_radius.html)
# LoadModule mod_radius.c
#
# Retrieve quota limit table information from a RADIUS server
# (http://www.proftpd.org/docs/contrib/mod_quotatab_radius.html)
# LoadModule mod_quotatab_radius.c
#
# SITE CPFR and SITE CPTO commands (analogous to RNFR and RNTO), which can be
# used to copy files/directories from one place to another on the server
# without having to transfer the data to the client and back
# (http://www.castaglia.org/proftpd/modules/mod_copy.html)
# LoadModule mod_copy.c
#
# Administrative control actions for the ftpdctl program
# (http://www.proftpd.org/docs/contrib/mod_ctrls_admin.html)
LoadModule mod_ctrls_admin.c
#
# Support for MODE Z commands, which allows FTP clients and servers to
# compress data for transfer
# (http://www.castaglia.org/proftpd/modules/mod_deflate.html)
# LoadModule mod_deflate.c
#
# Execute external programs or scripts at various points in the process
# of handling FTP commands
# (http://www.castaglia.org/proftpd/modules/mod_exec.html)
# LoadModule mod_exec.c
#
# Support for POSIX ACLs
# (http://www.proftpd.org/docs/modules/mod_facl.html)
# LoadModule mod_facl.c
#
# Support for using the GeoIP library to look up geographical information on
# the connecting client and using that to set access controls for the server
# (http://www.castaglia.org/proftpd/modules/mod_geoip.html)
# LoadModule mod_geoip.c
#
# Allow for version-specific configuration sections of the proftpd config file,
# useful for using the same proftpd config across multiple servers where
# different proftpd versions may be in use
# (http://www.castaglia.org/proftpd/modules/mod_ifversion.html)
# LoadModule mod_ifversion.c
#
# Configure server availability based on system load
# (http://www.proftpd.org/docs/contrib/mod_load.html)
# LoadModule mod_load.c
#
# Limit downloads to a multiple of upload volume (see README.ratio)
# LoadModule mod_ratio.c
#
# Rewrite FTP commands sent by clients on-the-fly,
# using regular expression matching and substitution
# (http://www.proftpd.org/docs/contrib/mod_rewrite.html)
# LoadModule mod_rewrite.c
#
# Support for the SSH2, SFTP, and SCP protocols, for secure file transfer over
# an SSH2 connection (http://www.castaglia.org/proftpd/modules/mod_sftp.html)
# LoadModule mod_sftp.c
#
# Use PAM to provide a 'keyboard-interactive' SSH2 authentication method for
# mod_sftp (http://www.castaglia.org/proftpd/modules/mod_sftp_pam.html)
# LoadModule mod_sftp_pam.c
#
# Use SQL (via mod_sql) for looking up authorized SSH2 public keys for user
# and host based authentication
# (http://www.castaglia.org/proftpd/modules/mod_sftp_sql.html)
# LoadModule mod_sftp_sql.c
#
# Provide data transfer rate "shaping" across the entire server
# (http://www.castaglia.org/proftpd/modules/mod_shaper.html)
# LoadModule mod_shaper.c
#
# Support for miscellaneous SITE commands such as SITE MKDIR, SITE SYMLINK,
# and SITE UTIME (http://www.proftpd.org/docs/contrib/mod_site_misc.html)
# LoadModule mod_site_misc.c
#
# Provide an external SSL session cache using shared memory
# (contrib/mod_tls_shmcache.html)
# LoadModule mod_tls_shmcache.c
#
# Provide a memcached-based implementation of an external SSL session cache
# (contrib/mod_tls_memcache.html)
# LoadModule mod_tls_memcache.c
#
# Use the /etc/hosts.allow and /etc/hosts.deny files, or other allow/deny
# files, for IP-based access control
# (http://www.proftpd.org/docs/contrib/mod_wrap.html)
# LoadModule mod_wrap.c
#
# Use the /etc/hosts.allow and /etc/hosts.deny files, or other allow/deny
# files, as well as SQL-based access rules, for IP-based access control
# (http://www.proftpd.org/docs/contrib/mod_wrap2.html)
# LoadModule mod_wrap2.c
#
# Support module for mod_wrap2 that handles access rules stored in specially
# formatted files on disk
# (http://www.proftpd.org/docs/contrib/mod_wrap2_file.html)
# LoadModule mod_wrap2_file.c
#
# Support module for mod_wrap2 that handles access rules stored in SQL
# database tables (http://www.proftpd.org/docs/contrib/mod_wrap2_sql.html)
# LoadModule mod_wrap2_sql.c
#
# Implement a virtual chroot capability that does not require root privileges
# (http://www.castaglia.org/proftpd/modules/mod_vroot.html)
# Using this module rather than the kernel's chroot() system call works
# around issues with PAM and chroot (http://bugzilla.redhat.com/506735)
LoadModule mod_vroot.c
#
# Provide a flexible way of specifying that certain configuration directives
# only apply to certain sessions, based on credentials such as connection
# class, user, or group membership
# (http://www.proftpd.org/docs/contrib/mod_ifsession.html)
# LoadModule mod_ifsession.c
# Allow only user root to load and unload modules, but allow everyone
# to see which modules have been loaded
# (http://www.proftpd.org/docs/modules/mod_dso.html#ModuleControlsACLs)
ModuleControlsACLs insmod,rmmod allow user root
ModuleControlsACLs lsmod allow user *
# Enable basic controls via ftpdctl # Enable basic controls via ftpdctl
# (http://www.proftpd.org/docs/modules/mod_ctrls.html) # (http://www.proftpd.org/docs/modules/mod_ctrls.html)
@ -295,50 +138,22 @@ ControlsLog /var/log/proftpd/controls.log
</IfModule> </IfModule>
# TLS (http://www.castaglia.org/proftpd/modules/mod_tls.html) # TLS (http://www.castaglia.org/proftpd/modules/mod_tls.html)
# Enable this with PROFTPD_OPTIONS=-DTLS in /etc/sysconfig/proftpd
<IfDefine TLS> <IfDefine TLS>
TLSEngine on Include /etc/proftpd/mod_tls.conf
TLSRequired off
TLSCertificateChainFile /etc/pki/tls/certs/proftpd-chain.pem
TLSRSACertificateFile /etc/pki/tls/certs/proftpd-cert.pem
TLSRSACertificateKeyFile /etc/pki/tls/private/proftpd-key.pem
TLSCipherSuite PROFILE=SYSTEM
# Relax the requirement that the SSL session be re-used for data transfers
TLSOptions NoSessionReuseRequired
TLSLog /var/log/proftpd/tls.log
<IfModule mod_tls_shmcache.c>
TLSSessionCache shm:/file=/var/run/proftpd/sesscache
</IfModule>
</IfDefine> </IfDefine>
# Dynamic ban lists (http://www.proftpd.org/docs/contrib/mod_ban.html) # Dynamic ban lists (http://www.proftpd.org/docs/contrib/mod_ban.html)
# Enable this with PROFTPD_OPTIONS=-DDYNAMIC_BAN_LISTS in /etc/sysconfig/proftpd # Enable this with PROFTPD_OPTIONS=-DDYNAMIC_BAN_LISTS in /etc/sysconfig/proftpd
<IfDefine DYNAMIC_BAN_LISTS> <IfModule mod_ban.c>
LoadModule mod_ban.c Include /etc/proftpd/mod_ban.conf
BanEngine on </IfModule>
BanLog /var/log/proftpd/ban.log
BanTable /var/run/proftpd/ban.tab
# If the same client reaches the MaxLoginAttempts limit 2 times
# within 10 minutes, automatically add a ban for that client that
# will expire after one hour.
BanOnEvent MaxLoginAttempts 2/00:10:00 01:00:00
# Inform the user that it's not worth persisting
BanMessage "Host %a has been banned"
# Allow the FTP admin to manually add/remove bans
BanControlsACLs all allow user ftpadm
</IfDefine>
# Set networking-specific "Quality of Service" (QoS) bits on the packets used # Set networking-specific "Quality of Service" (QoS) bits on the packets used
# by the server (contrib/mod_qos.html) # by the server (http://www.proftpd.org/docs/contrib/mod_qos.html)
<IfDefine QOS> <IfModule mod_qos.c>
LoadModule mod_qos.c Include /etc/proftpd/mod_qos.conf
# RFC791 TOS parameter compatibility </IfModule>
QoSOptions dataqos throughput ctrlqos lowdelay
# For a DSCP environment (may require tweaking)
#QoSOptions dataqos CS2 ctrlqos AF41
</IfDefine>
# Global Config - config common to Server Config and all virtual hosts # Global Config - config common to Server Config and all virtual hosts
# See: http://www.proftpd.org/docs/howto/Vhost.html # See: http://www.proftpd.org/docs/howto/Vhost.html
@ -359,73 +174,9 @@ ControlsLog /var/log/proftpd/controls.log
# A basic anonymous configuration, with an upload directory # A basic anonymous configuration, with an upload directory
# Enable this with PROFTPD_OPTIONS=-DANONYMOUS_FTP in /etc/sysconfig/proftpd # Enable this with PROFTPD_OPTIONS=-DANONYMOUS_FTP in /etc/sysconfig/proftpd
<IfDefine ANONYMOUS_FTP> <IfDefine ANONYMOUS_FTP>
<Anonymous ~ftp> Include /etc/proftpd/anonftp.conf
User ftp
Group ftp
AccessGrantMsg "Anonymous login ok, restrictions apply."
# We want clients to be able to login with "anonymous" as well as "ftp"
UserAlias anonymous ftp
# Limit the maximum number of anonymous logins
MaxClients 10 "Sorry, max %m users -- try again later"
# Put the user into /pub right after login
#DefaultChdir /pub
# We want 'welcome.msg' displayed at login, '.message' displayed in
# each newly chdired directory and tell users to read README* files.
DisplayLogin /welcome.msg
DisplayChdir .message
DisplayReadme README*
# Cosmetic option to make all files appear to be owned by user "ftp"
DirFakeUser on ftp
DirFakeGroup on ftp
# Limit WRITE everywhere in the anonymous chroot
<Limit WRITE SITE_CHMOD>
DenyAll
</Limit>
# An upload directory that allows storing files but not retrieving
# or creating directories.
#
# Directory specification is slightly different if mod_vroot is in
# use: see http://sourceforge.net/p/proftp/mailman/message/31728570/
# https://bugzilla.redhat.com/show_bug.cgi?id=1045922
<IfModule mod_vroot.c>
<Directory /uploads/*>
AllowOverwrite no
<Limit READ>
DenyAll
</Limit>
<Limit STOR>
AllowAll
</Limit>
</Directory>
</IfModule>
<IfModule !mod_vroot.c>
<Directory uploads/*>
AllowOverwrite no
<Limit READ>
DenyAll
</Limit>
<Limit STOR>
AllowAll
</Limit>
</Directory>
</IfModule>
# Don't write anonymous accesses to the system wtmp file (good idea!)
WtmpLog off
# Logging for the anonymous transfers
ExtendedLog /var/log/proftpd/access.log WRITE,READ default
ExtendedLog /var/log/proftpd/auth.log AUTH auth
</Anonymous>
</IfDefine> </IfDefine>
# Include other custom configuration files
Include /etc/proftpd/conf.d/*.conf

View File

@ -1,6 +1,6 @@
--- proftpd.conf 2011-04-05 11:59:10.491108239 +0100 --- modules.conf
+++ proftpd.conf 2010-12-23 15:19:13.667374844 +0000 +++ modules.conf
@@ -167,10 +167,6 @@ @@ -130,10 +130,6 @@
# (contrib/mod_tls_shmcache.html) # (contrib/mod_tls_shmcache.html)
# LoadModule mod_tls_shmcache.c # LoadModule mod_tls_shmcache.c
# #

55
proftpd.rpmlintrc Normal file
View File

@ -0,0 +1,55 @@
from Config import *
# Technical terms spelled correctly
addFilter("spelling-error %description -l en_US customizable -> ")
addFilter("spelling-error %description -l en_US passwd -> ")
addFilter("spelling-error %description -l en_US systemd -> ")
addFilter("spelling-error %description -l en_US virtualhost -> ")
addFilter("spelling-error %description -l en_US xinetd -> ")
# Proftpd allows specification of ciphers; mod_tls.conf specifies system default
addFilter("crypto-policy-non-compliance-openssl /usr/sbin/proftpd SSL_CTX_set_cipher_list")
# All FTP daemons provide this
addFilter("unversioned-explicit-provides ftpserver")
# This is the correct place for tmpfiles snippets
addFilter("hardcoded-library-path in %{_prefix}/lib/tmpfiles.d")
addFilter("only-non-binary-in-usr-lib")
# These modes are intentional
addFilter("non-readable /etc/proftpd.conf 640")
addFilter("non-readable /etc/proftpd/anonftp.conf 640")
addFilter("non-readable /etc/proftpd/mod_ban.conf 640")
addFilter("non-readable /etc/proftpd/mod_qos.conf 640")
addFilter("non-readable /etc/proftpd/mod_tls.conf 640")
addFilter("non-readable /etc/proftpd/modules.conf 640")
addFilter("non-standard-dir-perm /var/ftp/uploads 331")
addFilter("non-standard-dir-perm /var/log/proftpd 750")
# /var/run/proftpd maintained by tmpfiles snippet too
# Owning the directories in the package allows the daemon to run immediately after install, with no reboot
addFilter("dir-or-file-in-var-run /var/run/proftpd")
addFilter("non-ghost-in-run /run/proftpd")
# File should exist but have no default content
addFilter("zero-length /etc/ftpusers")
# Same manpage as proftpd
addFilter("no-manual-page-for-binary in.proftpd")
# This is normal for libtool projects
addFilter("hidden-file-or-dir /usr/src/debug/proftpd-.*/\.libs")
# Upstream does not provide documentation for devel tools/API yet
addFilter("no-documentation")
addFilter("no-manual-page-for-binary prxs")
# https://github.com/proftpd/proftpd/pull/493
# https://github.com/proftpd/proftpd/commit/75ed08ffe309b75b78dfcdeb4164d88ced4b0888
# These should be fixed in 1.3.7
addFilter("incorrect-fsf-address /usr/src/debug/proftpd-.*/modules/mod_geoip.c")
addFilter("incorrect-fsf-address /usr/include/proftpd/ident.h")
addFilter("incorrect-fsf-address /usr/include/proftpd/utf8.h")
addFilter("incorrect-fsf-address /usr/include/proftpd/lastlog.h")

View File

@ -1,96 +1,111 @@
%global use_systemd 1 # With systemd, the runtime directory is /run on tmpfs rather than /var/run on persistent storage
%global rundir /run %global use_systemd 1
%global rundir_tmpfs 1 %global rundir /run
%global rundir_tmpfs 1
%global systemd_units systemd %global systemd_units systemd
%global preset_support 1 %global preset_support 1
%global mysql_lib mariadb %global mysql_lib mariadb
%global mysql_devel_pkg mariadb-connector-c-devel %global mysql_devel_pkg mariadb-connector-c-devel
%global postgresql_devel_pkg libpq-devel
%global _hardened_build 1
%undefine _strict_symbol_defs_build
%global rpmrel 20
%global mod_vroot_version 0.9.5
%bcond_with enable_test 0
Name: proftpd # Do a hardened build where possible
Version: 1.3.6 %global _hardened_build 1
Release: 1
Summary: Flexible, stable and highly-configurable FTP server # Dynamic modules contain references to symbols in main dæmon, so we need to disable linker checks for undefined symbols
License: GPLv2+ %undefine _strict_symbol_defs_build
URL: https://github.com/proftpd/proftpd
Source0: https://github.com/proftpd/proftpd/archive/v%{version}.tar.gz %global mod_vroot_version 0.9.5
Source1: proftpd.conf
Source5: proftpd-welcome.msg Name: proftpd
Source9: proftpd.sysconfig Version: 1.3.7a
Source10: http://github.com/Castaglia/proftpd-mod_vroot/archive/v%{mod_vroot_version}.tar.gz Release: 1
Patch1: proftpd-1.3.6-shellbang.patch Summary: Flexible, stable and highly-configurable FTP server
Patch2: proftpd.conf-no-memcached.patch License: GPLv2+
Patch3: proftpd-1.3.4rc1-mod_vroot-test.patch URL: http://www.proftpd.org/
# https://github.com/proftpd/proftpd/commit/459693c7.patch
Patch100: 459693c7.patch Source0: https://github.com/proftpd/proftpd/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
# https://github.com/proftpd/proftpd/commit/389cc579.patch Source1: proftpd.conf
Patch101: 389cc579.patch Source2: modules.conf
# https://github.com/proftpd/proftpd/commit/1825a2b8.patch Source3: mod_tls.conf
Patch102: 1825a2b8.patch Source4: mod_ban.conf
# https://github.com/proftpd/proftpd/commit/73887e02.patch Source5: mod_qos.conf
Patch103: 73887e02.patch Source6: anonftp.conf
# https://github.com/proftpd/proftpd/commit/8a186e2d.patch Source8: proftpd-welcome.msg
Patch104: 8a186e2d.patch Source9: proftpd.sysconfig
# https://github.com/proftpd/proftpd/commit/c3e5d75f.patch Source10: http://github.com/Castaglia/proftpd-mod_vroot/archive/v%{mod_vroot_version}.tar.gz
Patch105: c3e5d75f.patch
Patch106: proftpd-1.3.6-add-enable-tests-nonetwork-option.patch Patch1: proftpd-1.3.7-shellbang.patch
# https://github.com/proftpd/proftpd/commit/adfdc01d.patch Patch2: proftpd.conf-no-memcached.patch
Patch107: adfdc01d.patch Patch3: proftpd-1.3.4rc1-mod_vroot-test.patch
# https://github.com/proftpd/proftpd/commit/6cc96b5f.patch Patch4: proftpd-1.3.6-no-mod-wrap.patch
Patch108: 6cc96b5f.patch Patch5: proftpd-1.3.6-no-mod-geoip.patch
# https://github.com/proftpd/proftpd/commit/aa85f127.patch Patch6: proftpd-1.3.7rc3-logging-not-systemd.patch
Patch109: aa85f127.patch Patch7: proftpd-1.3.7a-check-api.patch
# https://github.com/proftpd/proftpd/commit/7907aa65.patch Patch8: proftpd-1.3.7a-netaddr-test.patch
Patch110: 7907aa65.patch Patch9: proftpd-1.3.7a-fix-environment-sensitive-tests-failure.patch
# https://github.com/proftpd/proftpd/commit/08ba2f63.patch Patch10: proftpd-1.3.7a-Adjusting-unit-test-timeouts-for-netaddr.patch
Patch111: 08ba2f63.patch Patch11: proftpd-1.3.7a-Adjusting-unit-test-timeouts-for-netacl.patch
# https://github.com/proftpd/proftpd/commit/757b9633.patch
Patch112: 757b9633.patch BuildRequires: coreutils
# https://github.com/proftpd/proftpd/commit/41ecb7dc.patch BuildRequires: gcc
Patch113: 41ecb7dc.patch BuildRequires: gettext
# https://github.com/proftpd/proftpd/commit/ad786eaa.patch BuildRequires: libacl-devel
Patch114: ad786eaa.patch BuildRequires: libcap-devel
# https://github.com/proftpd/proftpd/commit/a2c02a6b.patch BuildRequires: logrotate
Patch115: a2c02a6b.patch BuildRequires: %{mysql_devel_pkg}
Patch116: proftpd-1.3.6-ENOATTR.patch BuildRequires: ncurses-devel
# https://github.com/proftpd/proftpd/commit/fa378a8f.patch BuildRequires: openldap-devel
Patch117: fa378a8f.patch BuildRequires: openssl-devel
BuildRequires: coreutils gcc GeoIP-devel gettext libacl-devel libcap-devel BuildRequires: pam-devel
%if 0%{?have_libmemcached:1} BuildRequires: pcre-devel >= 7.0
BuildRequires: libmemcached-devel >= 0.41 BuildRequires: perl-interpreter
%endif BuildRequires: pkgconfig
BuildRequires: %{mysql_devel_pkg} ncurses-devel openldap-devel openssl-devel BuildRequires: postgresql-devel
BuildRequires: pam-devel pcre-devel >= 7.0 perl-generators perl-interpreter BuildRequires: sed
BuildRequires: pkgconfig %{postgresql_devel_pkg} sqlite-devel tar BuildRequires: sqlite-devel
%if 0%{?libwrap_support:1} BuildRequires: tar
BuildRequires: tcp_wrappers-devel BuildRequires: zlib-devel
%endif
BuildRequires: zlib-devel # Test suite requirements
BuildRequires: check-devel BuildRequires: check-devel
%if 0%{?_with_integrationtests:1} %if 0%{?_with_integrationtests:1}
BuildRequires: perl(Compress::Zlib) perl(Digest::MD5) perl(HTTP::Request) BuildRequires: perl(Compress::Zlib)
BuildRequires: perl(IO::Socket::SSL) perl(LWP::UserAgent) perl(Net::FTPSSL) BuildRequires: perl(Digest::MD5)
BuildRequires: perl(Net::SSLeay) perl(Net::Telnet) perl(Sys::HostAddr) perl(Test::Harness) BuildRequires: perl(HTTP::Request)
BuildRequires: perl(Test::Unit) >= 0.25 perl(Time::HiRes) BuildRequires: perl(IO::Socket::SSL)
BuildRequires: perl(LWP::UserAgent)
BuildRequires: perl(Net::FTPSSL)
BuildRequires: perl(Net::SSLeay)
BuildRequires: perl(Net::Telnet)
BuildRequires: perl(Sys::HostAddr)
BuildRequires: perl(Test::Harness)
BuildRequires: perl(Test::Unit) >= 0.25
BuildRequires: perl(Time::HiRes)
%endif %endif
# Need %%{systemd_units} for ownership of /usr/lib/tmpfiles.d directory
%if %{rundir_tmpfs} %if %{rundir_tmpfs}
Requires: %{systemd_units} Requires: %{systemd_units}
%endif %endif
Requires(preun):coreutils, findutils
# Logs should be rotated periodically
Requires: logrotate
# Scriptlet dependencies
Requires(preun): coreutils, findutils
%if %{use_systemd} %if %{use_systemd}
BuildRequires: %{systemd_units} BuildRequires: %{systemd_units}
%{?systemd_requires} %{?systemd_requires}
%else %else
Requires(post): chkconfig Requires(post): chkconfig
Requires(preun): chkconfig, initscripts Requires(preun): chkconfig, initscripts
Requires(postun):initscripts Requires(postun): initscripts
%endif %endif
Provides: ftpserver
Provides: ftpserver
%description %description
ProFTPD is an enhanced FTP server with a focus toward simplicity, security, ProFTPD is an enhanced FTP server with a focus toward simplicity, security,
and ease of configuration. It features a very Apache-like configuration and ease of configuration. It features a very Apache-like configuration
@ -105,54 +120,65 @@ This package defaults to the standalone behavior of ProFTPD, but all the
needed scripts to have it run by xinetd instead are included. needed scripts to have it run by xinetd instead are included.
%endif %endif
%package devel %package devel
Summary: ProFTPD - Tools and header files for developers Summary: ProFTPD - Tools and header files for developers
Requires: %{name} = %{version}-%{release} gcc libtool GeoIP-devel libacl-devel Requires: %{name} = %{version}-%{release}
Requires: libcap-devel # devel package requires the same devel packages as were build-required
%if 0%{?have_libmemcached:1} # for the main package
Requires: libmemcached-devel >= 0.41 Requires: gcc, libtool
%endif Requires: libacl-devel
Requires: %{mysql_devel_pkg} ncurses-devel openldap-devel openssl-devel pam-devel Requires: libcap-devel
Requires: pcre-devel pkgconfig %{postgresql_devel_pkg} sqlite-devel Requires: %{mysql_devel_pkg}
%if 0%{?libwrap_support:1} Requires: ncurses-devel
Requires: tcp_wrappers-devel Requires: openldap-devel
%endif Requires: openssl-devel
Requires: zlib-devel Requires: pam-devel
Requires: pcre-devel
Requires: pkgconfig
Requires: postgresql-devel
Requires: sqlite-devel
Requires: zlib-devel
%description devel %description devel
This package is required to build additional modules for ProFTPD. This package is required to build additional modules for ProFTPD.
%package ldap %package ldap
Summary: Module to add LDAP support to the ProFTPD FTP server Summary: Module to add LDAP support to the ProFTPD FTP server
Requires: %{name} = %{version}-%{release} Requires: %{name} = %{version}-%{release}
%description ldap %description ldap
Module to add LDAP support to the ProFTPD FTP server. Module to add LDAP support to the ProFTPD FTP server.
%package mysql %package mysql
Summary: Module to add MySQL support to the ProFTPD FTP server Summary: Module to add MySQL support to the ProFTPD FTP server
Requires: %{name} = %{version}-%{release} Requires: %{name} = %{version}-%{release}
%description mysql %description mysql
Module to add MySQL support to the ProFTPD FTP server. Module to add MySQL support to the ProFTPD FTP server.
%package postgresql %package postgresql
Summary: Module to add PostgreSQL support to the ProFTPD FTP server Summary: Module to add PostgreSQL support to the ProFTPD FTP server
Requires: %{name} = %{version}-%{release} Requires: %{name} = %{version}-%{release}
%description postgresql %description postgresql
Module to add PostgreSQL support to the ProFTPD FTP server. Module to add PostgreSQL support to the ProFTPD FTP server.
%package sqlite %package sqlite
Summary: Module to add SQLite support to the ProFTPD FTP server Summary: Module to add SQLite support to the ProFTPD FTP server
Requires: %{name} = %{version}-%{release} Requires: %{name} = %{version}-%{release}
%description sqlite %description sqlite
Module to add SQLite support to the ProFTPD FTP server. Module to add SQLite support to the ProFTPD FTP server.
%package utils %package utils
Summary: ProFTPD - Additional utilities Summary: ProFTPD - Additional utilities
Requires: %{name} = %{version}-%{release} perl-interpreter Requires: %{name} = %{version}-%{release}
BuildRequires:perl(Crypt::Cracklib) Requires: perl-interpreter
Requires: perl(Crypt::Cracklib)
%description utils %description utils
This package contains additional utilities for monitoring and configuring the This package contains additional utilities for monitoring and configuring the
ProFTPD server: ProFTPD server:
* ftpasswd: generate passwd(5) files for use with AuthUserFile * ftpasswd: generate passwd(5) files for use with AuthUserFile
* ftpcount: show the current number of connections per server/virtualhost * ftpcount: show the current number of connections per server/virtualhost
* ftpmail: monitor transfer log and send email when files uploaded * ftpmail: monitor transfer log and send email when files uploaded
@ -162,153 +188,188 @@ ProFTPD server:
%prep %prep
%setup -q -n %{name}-%{version}%{?prever} %setup -q -n %{name}-%{version}%{?prever}
# Extract mod_vroot source into contrib/
# Directory must be named mod_vroot for configure script to find it
cd contrib cd contrib
tar xfz %{SOURCE10} tar xfz %{SOURCE10}
mv proftpd-mod_vroot-%{mod_vroot_version} mod_vroot mv proftpd-mod_vroot-%{mod_vroot_version} mod_vroot
cd - cd -
cp -p %{SOURCE1} proftpd.conf
# Default config files
sed -e 's|@RUNDIR@|%{rundir}|' %{SOURCE1} > proftpd.conf
sed -e 's|@RUNDIR@|%{rundir}|' %{SOURCE2} > modules.conf
sed -e 's|@RUNDIR@|%{rundir}|' %{SOURCE3} > mod_tls.conf
sed -e 's|@RUNDIR@|%{rundir}|' %{SOURCE4} > mod_ban.conf
sed -e 's|@RUNDIR@|%{rundir}|' %{SOURCE5} > mod_qos.conf
sed -e 's|@RUNDIR@|%{rundir}|' %{SOURCE6} > anonftp.conf
# Avoid documentation name conflicts
mv contrib/README contrib/README.contrib mv contrib/README contrib/README.contrib
# Change shellbangs /usr/bin/env perl ⇒ /usr/bin/perl
%patch1 %patch1
%if 0%{!?have_libmemcached:1}
# If we don't have libmemcached support, remove the mod_tls_memcache
# snippet from the config file
%patch2 %patch2
%endif
# If we're running the full test suite, include the mod_vroot test
%patch3 -p1 -b .test_vroot %patch3 -p1 -b .test_vroot
%patch100 -p1
%patch101 -p1 # Remove references to mod_wrap from the configuration file if necessary
%patch102 -p1 %patch4 -b .nowrappers
%patch103 -p1
%patch104 -p1 # Remove references to mod_geoip from the configuration file if necessary
%patch105 -p1 %patch5 -b .nogeoip
%patch106 -p1
%patch107 -p1
%patch108 -p1
%patch109 -p1
%patch110 -p1
%patch111 -p1
%patch112 -p1
%patch113 -p1
%patch114 -p1
%patch115 -p1
%patch116 -p1
%patch117 -p1
%if %{use_systemd} %if %{use_systemd}
# Tweak logrotate script for systemd compatibility (#802178)
sed -i -e '/killall/s/test.*/systemctl reload proftpd.service/' \ sed -i -e '/killall/s/test.*/systemctl reload proftpd.service/' \
contrib/dist/rpm/proftpd.logrotate contrib/dist/rpm/proftpd.logrotate
%else
# Not using systemd, so we want hostname and timestamp in log messages
%patch6
%endif %endif
# Handle changed API in check 0.15
# https://bugzilla.redhat.com/show_bug.cgi?id=1850198
%patch7
# getaddrinfo() can return EAGAIN in netaddr api test
# https://github.com/proftpd/proftpd/pull/1075
%patch8
%patch9 -p1
%patch10 -p1
%patch11 -p1
# Avoid docfile dependencies
chmod -c -x contrib/xferstats.holger-preiss chmod -c -x contrib/xferstats.holger-preiss
# Remove bogus exec permissions from source files
chmod -c -x include/hanson-tpl.h lib/hanson-tpl.c chmod -c -x include/hanson-tpl.h lib/hanson-tpl.c
# Remove any patch backup files from documentation
find doc/ contrib/ -name '*.orig' -delete find doc/ contrib/ -name '*.orig' -delete
%build %build
# Modules to be built as DSO's (excluding mod_ifsession, always specified last)
SMOD1=mod_sql:mod_sql_passwd:mod_sql_mysql:mod_sql_postgres:mod_sql_sqlite SMOD1=mod_sql:mod_sql_passwd:mod_sql_mysql:mod_sql_postgres:mod_sql_sqlite
SMOD2=mod_quotatab:mod_quotatab_file:mod_quotatab_ldap:mod_quotatab_radius:mod_quotatab_sql SMOD2=mod_quotatab:mod_quotatab_file:mod_quotatab_ldap:mod_quotatab_radius:mod_quotatab_sql
SMOD3=mod_ldap:mod_ban%{?libwrap_support::mod_wrap}:mod_ctrls_admin:mod_facl:mod_load:mod_vroot SMOD3=mod_ldap:mod_ban:mod_ctrls_admin:mod_facl:mod_load:mod_vroot
SMOD4=mod_radius:mod_ratio:mod_rewrite:mod_site_misc:mod_exec:mod_shaper:mod_geoip SMOD4=mod_radius:mod_ratio:mod_rewrite:mod_site_misc:mod_exec:mod_shaper
SMOD5=mod_wrap2:mod_wrap2_file:mod_wrap2_sql:mod_copy:mod_deflate:mod_ifversion:mod_qos SMOD5=mod_wrap2:mod_wrap2_file:mod_wrap2_sql:mod_copy:mod_deflate:mod_ifversion:mod_qos
SMOD6=mod_sftp:mod_sftp_pam:mod_sftp_sql:mod_tls_shmcache%{?have_libmemcached::mod_tls_memcache} SMOD6=mod_sftp:mod_sftp_pam:mod_sftp_sql:mod_tls_shmcache
%configure \ %configure \
--libexecdir="%{_libexecdir}/proftpd" \ --libexecdir="%{_libexecdir}/proftpd" \
--localstatedir="%{rundir}/proftpd" \ --localstatedir="%{rundir}/proftpd" \
--disable-strip \ --disable-strip \
--enable-ctrls \ --enable-ctrls \
--enable-dso \ --enable-dso \
--enable-facl \ --enable-facl \
--enable-ipv6 \ --enable-ipv6 \
%{?have_libmemcached: --enable-memcache} \ --enable-nls \
--enable-nls \ --enable-openssl \
--enable-openssl \ --disable-pcre \
--disable-pcre \ --disable-redis \
--disable-redis \ --enable-shadow \
--enable-shadow \ --enable-tests=nonetwork \
--enable-tests=nonetwork \ --with-libraries="%{_libdir}/%{mysql_lib}" \
--with-libraries="%{_libdir}/%{mysql_lib}" \ --with-includes="%{_includedir}/mysql" \
--with-includes="%{_includedir}/mysql" \ --with-modules=mod_readme:mod_auth_pam:mod_tls \
--with-modules=mod_readme:mod_auth_pam:mod_tls \ --with-shared=${SMOD1}:${SMOD2}:${SMOD3}:${SMOD4}:${SMOD5}:${SMOD6}:mod_ifsession
--with-shared=${SMOD1}:${SMOD2}:${SMOD3}:${SMOD4}:${SMOD5}:${SMOD6}:mod_ifsession %make_build
make %{?_smp_mflags}
%install %install
make install DESTDIR=%{buildroot} \ %{make_install} INSTALL_USER=`id -un` INSTALL_GROUP=`id -gn`
rundir="%{rundir}/proftpd" \ mkdir -p %{buildroot}%{_sysconfdir}/proftpd/conf.d
INSTALL_USER=`id -un` \ install -D -p -m 640 proftpd.conf %{buildroot}%{_sysconfdir}/proftpd.conf
INSTALL_GROUP=`id -gn` install -D -p -m 640 anonftp.conf %{buildroot}%{_sysconfdir}/proftpd/anonftp.conf
install -D -p -m 640 proftpd.conf %{buildroot}%{_sysconfdir}/proftpd.conf install -D -p -m 640 modules.conf %{buildroot}%{_sysconfdir}/proftpd/modules.conf
install -D -p -m 640 mod_ban.conf %{buildroot}%{_sysconfdir}/proftpd/mod_ban.conf
install -D -p -m 640 mod_qos.conf %{buildroot}%{_sysconfdir}/proftpd/mod_qos.conf
install -D -p -m 640 mod_tls.conf %{buildroot}%{_sysconfdir}/proftpd/mod_tls.conf
install -D -p -m 644 contrib/dist/rpm/proftpd.pam \ install -D -p -m 644 contrib/dist/rpm/proftpd.pam \
%{buildroot}%{_sysconfdir}/pam.d/proftpd %{buildroot}%{_sysconfdir}/pam.d/proftpd
%if %{use_systemd} %if %{use_systemd}
install -D -p -m 644 contrib/dist/rpm/proftpd.service \ install -D -p -m 644 contrib/dist/rpm/proftpd.service \
%{buildroot}%{_unitdir}/proftpd.service %{buildroot}%{_unitdir}/proftpd.service
install -D -p -m 644 contrib/dist/systemd/proftpd.socket \ install -D -p -m 644 contrib/dist/systemd/proftpd.socket \
%{buildroot}%{_unitdir}/proftpd.socket %{buildroot}%{_unitdir}/proftpd.socket
install -D -p -m 644 contrib/dist/systemd/proftpd@.service \ install -D -p -m 644 contrib/dist/systemd/proftpd@.service \
%{buildroot}%{_unitdir}/proftpd@.service %{buildroot}%{_unitdir}/proftpd@.service
%else %else
install -D -p -m 755 contrib/dist/rpm/proftpd.init.d \ install -D -p -m 755 contrib/dist/rpm/proftpd.init.d \
%{buildroot}%{_sysconfdir}/rc.d/init.d/proftpd %{buildroot}%{_sysconfdir}/rc.d/init.d/proftpd
install -D -p -m 644 contrib/dist/rpm/xinetd \ install -D -p -m 644 contrib/dist/rpm/xinetd \
%{buildroot}%{_sysconfdir}/xinetd.d/xproftpd %{buildroot}%{_sysconfdir}/xinetd.d/xproftpd
%endif %endif
install -D -p -m 644 contrib/dist/rpm/proftpd.logrotate \ install -D -p -m 644 contrib/dist/rpm/proftpd.logrotate \
%{buildroot}%{_sysconfdir}/logrotate.d/proftpd %{buildroot}%{_sysconfdir}/logrotate.d/proftpd
install -D -p -m 644 %{SOURCE5} %{buildroot}%{_localstatedir}/ftp/welcome.msg install -D -p -m 644 %{SOURCE8} %{buildroot}%{_localstatedir}/ftp/welcome.msg
install -D -p -m 644 %{SOURCE9} %{buildroot}%{_sysconfdir}/sysconfig/proftpd install -D -p -m 644 %{SOURCE9} %{buildroot}%{_sysconfdir}/sysconfig/proftpd
mkdir -p %{buildroot}%{_localstatedir}/{ftp/{pub,uploads},log/proftpd} mkdir -p %{buildroot}%{_localstatedir}/{ftp/{pub,uploads},log/proftpd}
touch %{buildroot}%{_sysconfdir}/ftpusers touch %{buildroot}%{_sysconfdir}/ftpusers
# Make sure %%{rundir}/proftpd exists at boot time for systems where it's on tmpfs (#656675)
%if %{rundir_tmpfs} %if %{rundir_tmpfs}
install -d -m 755 %{buildroot}%{_prefix}/lib/tmpfiles.d install -d -m 755 %{buildroot}%{_prefix}/lib/tmpfiles.d
install -p -m 644 contrib/dist/rpm/proftpd-tmpfs.conf \ install -p -m 644 contrib/dist/rpm/proftpd-tmpfs.conf \
%{buildroot}%{_prefix}/lib/tmpfiles.d/proftpd.conf %{buildroot}%{_prefix}/lib/tmpfiles.d/proftpd.conf
%endif %endif
# Find translations
%find_lang proftpd %find_lang proftpd
%if %{with enable_test}
%check %check
# Integration tests not fully maintained - stick to API tests only by default
%if 0%{?_with_integrationtests:1} %if 0%{?_with_integrationtests:1}
ln ftpdctl tests/ ln ftpdctl tests/
make check make check
%else %else
# API tests should always be OK
export HOSTNAME=`cat /etc/hosts | grep 127.0.0.1 | head -1| awk '{print $2}'`
if ! make -C tests api-tests; then if ! make -C tests api-tests; then
# Diagnostics to report upstream # Diagnostics to report upstream
cat tests/api-tests.log cat tests/api-tests.log
./proftpd -V ./proftpd -V
# Fail the build # Fail the build
false false
fi fi
%endif %endif
%endif
%post %post
%if %{use_systemd} %if %{use_systemd}
systemctl daemon-reload &>/dev/null || : systemctl daemon-reload &>/dev/null || :
%endif %endif
if [ $1 -eq 1 ]; then if [ $1 -eq 1 ]; then
# Initial installation # Initial installation
%if ! %{use_systemd} %if ! %{use_systemd}
chkconfig --add proftpd || : chkconfig --add proftpd || :
%endif %endif
%if %{preset_support} %if %{preset_support}
systemctl preset proftpd.service &>/dev/null || : systemctl preset proftpd.service &>/dev/null || :
%endif %endif
IFS=":"; cat /etc/passwd | \ IFS=":"; cat /etc/passwd | \
while { read username nu nu gid nu nu nu nu; }; do \ while { read username nu nu gid nu nu nu nu; }; do \
if [ $gid -lt 100 -a "$username" != "ftp" ]; then if [ $gid -lt 100 -a "$username" != "ftp" ]; then
echo $username >> %{_sysconfdir}/ftpusers echo $username >> %{_sysconfdir}/ftpusers
fi fi
done done
fi fi
%preun %preun
if [ $1 -eq 0 ]; then if [ $1 -eq 0 ]; then
# Package removal, not upgrade # Package removal, not upgrade
%if %{use_systemd} %if %{use_systemd}
systemctl --no-reload disable proftpd.service &>/dev/null || : systemctl --no-reload disable proftpd.service &>/dev/null || :
systemctl stop proftpd.service &>/dev/null || : systemctl stop proftpd.service &>/dev/null || :
%else %else
service proftpd stop &>/dev/null || : service proftpd stop &>/dev/null || :
chkconfig --del proftpd || : chkconfig --del proftpd || :
%endif %endif
find %{rundir}/proftpd -depth -mindepth 1 | find %{rundir}/proftpd -depth -mindepth 1 |
xargs rm -rf &>/dev/null || : xargs rm -rf &>/dev/null || :
fi fi
%postun %postun
@ -316,14 +377,14 @@ fi
systemctl daemon-reload &>/dev/null || : systemctl daemon-reload &>/dev/null || :
%endif %endif
if [ $1 -ge 1 ]; then if [ $1 -ge 1 ]; then
# Package upgrade, not uninstall # Package upgrade, not uninstall
%if %{use_systemd} %if %{use_systemd}
systemctl try-restart proftpd.service &>/dev/null || : systemctl try-restart proftpd.service &>/dev/null || :
%else %else
service proftpd condrestart &>/dev/null || : service proftpd condrestart &>/dev/null || :
else else
# Package removal, not upgrade # Package removal, not upgrade
service xinetd reload &>/dev/null || : service xinetd reload &>/dev/null || :
%endif %endif
fi fi
@ -334,13 +395,14 @@ fi
%doc COPYING %doc COPYING
%endif %endif
%doc CREDITS ChangeLog NEWS README.md %doc CREDITS ChangeLog NEWS README.md
%doc README.DSO README.modules README.IPv6 README.PAM %doc README.modules contrib/README.contrib contrib/README.ratio
%doc README.capabilities README.classes README.controls README.facl
%doc contrib/README.contrib contrib/README.ratio
%doc doc/* sample-configurations/ %doc doc/* sample-configurations/
%dir %{_localstatedir}/ftp/ %dir %{_localstatedir}/ftp/
%dir %{_localstatedir}/ftp/pub/ %dir %{_localstatedir}/ftp/pub/
%dir %{rundir}/proftpd/ %dir %{rundir}/proftpd/
%dir %{_sysconfdir}/logrotate.d/
%dir %{_sysconfdir}/proftpd/
%dir %{_sysconfdir}/proftpd/conf.d/
%config(noreplace) %{_localstatedir}/ftp/welcome.msg %config(noreplace) %{_localstatedir}/ftp/welcome.msg
%config(noreplace) %{_sysconfdir}/blacklist.dat %config(noreplace) %{_sysconfdir}/blacklist.dat
%config(noreplace) %{_sysconfdir}/dhparams.pem %config(noreplace) %{_sysconfdir}/dhparams.pem
@ -348,6 +410,11 @@ fi
%config(noreplace) %{_sysconfdir}/logrotate.d/proftpd %config(noreplace) %{_sysconfdir}/logrotate.d/proftpd
%config(noreplace) %{_sysconfdir}/pam.d/proftpd %config(noreplace) %{_sysconfdir}/pam.d/proftpd
%config(noreplace) %{_sysconfdir}/proftpd.conf %config(noreplace) %{_sysconfdir}/proftpd.conf
%config(noreplace) %{_sysconfdir}/proftpd/anonftp.conf
%config(noreplace) %{_sysconfdir}/proftpd/modules.conf
%config(noreplace) %{_sysconfdir}/proftpd/mod_ban.conf
%config(noreplace) %{_sysconfdir}/proftpd/mod_qos.conf
%config(noreplace) %{_sysconfdir}/proftpd/mod_tls.conf
%config(noreplace) %{_sysconfdir}/sysconfig/proftpd %config(noreplace) %{_sysconfdir}/sysconfig/proftpd
%if %{use_systemd} %if %{use_systemd}
%{_unitdir}/proftpd.service %{_unitdir}/proftpd.service
@ -378,7 +445,6 @@ fi
%{_libexecdir}/proftpd/mod_deflate.so %{_libexecdir}/proftpd/mod_deflate.so
%{_libexecdir}/proftpd/mod_exec.so %{_libexecdir}/proftpd/mod_exec.so
%{_libexecdir}/proftpd/mod_facl.so %{_libexecdir}/proftpd/mod_facl.so
%{_libexecdir}/proftpd/mod_geoip.so
%{_libexecdir}/proftpd/mod_ifsession.so %{_libexecdir}/proftpd/mod_ifsession.so
%{_libexecdir}/proftpd/mod_ifversion.so %{_libexecdir}/proftpd/mod_ifversion.so
%{_libexecdir}/proftpd/mod_load.so %{_libexecdir}/proftpd/mod_load.so
@ -397,10 +463,8 @@ fi
%{_libexecdir}/proftpd/mod_site_misc.so %{_libexecdir}/proftpd/mod_site_misc.so
%{_libexecdir}/proftpd/mod_sql.so %{_libexecdir}/proftpd/mod_sql.so
%{_libexecdir}/proftpd/mod_sql_passwd.so %{_libexecdir}/proftpd/mod_sql_passwd.so
%{?have_libmemcached:%{_libexecdir}/proftpd/mod_tls_memcache.so}
%{_libexecdir}/proftpd/mod_tls_shmcache.so %{_libexecdir}/proftpd/mod_tls_shmcache.so
%{_libexecdir}/proftpd/mod_vroot.so %{_libexecdir}/proftpd/mod_vroot.so
%{?libwrap_support:%{_libexecdir}/proftpd/mod_wrap.so}
%{_libexecdir}/proftpd/mod_wrap2.so %{_libexecdir}/proftpd/mod_wrap2.so
%{_libexecdir}/proftpd/mod_wrap2_file.so %{_libexecdir}/proftpd/mod_wrap2_file.so
%{_libexecdir}/proftpd/mod_wrap2_sql.so %{_libexecdir}/proftpd/mod_wrap2_sql.so
@ -444,5 +508,8 @@ fi
%{_mandir}/man1/ftpwho.1* %{_mandir}/man1/ftpwho.1*
%changelog %changelog
* Tue Jun 1 2021 gaihuiying <gaihuiying1@huawei.com> - 1.3.7a-1
- Update to 1.3.7a
* Wed Oct 14 2020 chengzihan <chengzihan2@huawei.com> - 1.3.6-1 * Wed Oct 14 2020 chengzihan <chengzihan2@huawei.com> - 1.3.6-1
- Package init - Package init