Browse Source

added proftpd package

Signed-off-by: webbuilder_pel7ppc64bebuilder0 <webbuilder@powerel.org>
master
webbuilder_pel7ppc64bebuilder0 7 years ago
parent
commit
0672bc5cc4
  1. 78
      SOURCES/08ba2f63.patch
  2. 23
      SOURCES/1825a2b8.patch
  3. 206
      SOURCES/389cc579.patch
  4. 326
      SOURCES/41ecb7dc.patch
  5. 31
      SOURCES/459693c7.patch
  6. 37
      SOURCES/6cc96b5f.patch
  7. 66
      SOURCES/73887e02.patch
  8. 119
      SOURCES/757b9633.patch
  9. 47
      SOURCES/7907aa65.patch
  10. 147
      SOURCES/8a186e2d.patch
  11. 159
      SOURCES/aa85f127.patch
  12. 23
      SOURCES/ad786eaa.patch
  13. 25
      SOURCES/adfdc01d.patch
  14. 97
      SOURCES/c3e5d75f.patch
  15. 14
      SOURCES/proftpd-1.3.4rc1-mod_vroot-test.patch
  16. 186
      SOURCES/proftpd-1.3.6-add-enable-tests-nonetwork-option.patch
  17. 14
      SOURCES/proftpd-1.3.6-no-mod-wrap.patch
  18. 40
      SOURCES/proftpd-1.3.6-shellbang.patch
  19. 6
      SOURCES/proftpd-welcome.msg
  20. 430
      SOURCES/proftpd.conf
  21. 13
      SOURCES/proftpd.conf-no-memcached.patch
  22. 12
      SOURCES/proftpd.sysconfig
  23. 1602
      SPECS/proftpd.spec

78
SOURCES/08ba2f63.patch

@ -0,0 +1,78 @@ @@ -0,0 +1,78 @@
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);

23
SOURCES/1825a2b8.patch

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
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

206
SOURCES/389cc579.patch

@ -0,0 +1,206 @@ @@ -0,0 +1,206 @@
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

326
SOURCES/41ecb7dc.patch

@ -0,0 +1,326 @@ @@ -0,0 +1,326 @@
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};

31
SOURCES/459693c7.patch

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
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);
}

37
SOURCES/6cc96b5f.patch

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
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

66
SOURCES/73887e02.patch

@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
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();

119
SOURCES/757b9633.patch

@ -0,0 +1,119 @@ @@ -0,0 +1,119 @@
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.

47
SOURCES/7907aa65.patch

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
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());

147
SOURCES/8a186e2d.patch

@ -0,0 +1,147 @@ @@ -0,0 +1,147 @@
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);

159
SOURCES/aa85f127.patch

@ -0,0 +1,159 @@ @@ -0,0 +1,159 @@
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};

23
SOURCES/ad786eaa.patch

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
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

25
SOURCES/adfdc01d.patch

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
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]

97
SOURCES/c3e5d75f.patch

@ -0,0 +1,97 @@ @@ -0,0 +1,97 @@
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]);

14
SOURCES/proftpd-1.3.4rc1-mod_vroot-test.patch

@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
--- 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
@@ -283,6 +283,11 @@
test_class => [qw(mod_unique_id)],
},

+ 't/modules/mod_vroot.t' => {
+ order => ++$order,
+ test_class => [qw(mod_vroot)],
+ },
+
't/modules/mod_wrap.t' => {
order => ++$order,
test_class => [qw(mod_wrap)],

186
SOURCES/proftpd-1.3.6-add-enable-tests-nonetwork-option.patch

@ -0,0 +1,186 @@ @@ -0,0 +1,186 @@
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

14
SOURCES/proftpd-1.3.6-no-mod-wrap.patch

@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
--- proftpd.conf
+++ proftpd.conf
@@ -238,11 +238,6 @@ LoadModule mod_ctrls_admin.c
# 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

40
SOURCES/proftpd-1.3.6-shellbang.patch

@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
--- contrib/ftpasswd
+++ contrib/ftpasswd
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl
+#!/usr/bin/perl
# ---------------------------------------------------------------------------
# Copyright (C) 2000-2015 TJ Saunders <tj@castaglia.org>
#
--- contrib/ftpmail
+++ contrib/ftpmail
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl
+#!/usr/bin/perl
# ---------------------------------------------------------------------------
# Copyright (C) 2008-2013 TJ Saunders <tj@castaglia.org>
#
--- contrib/ftpquota
+++ contrib/ftpquota
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl
+#!/usr/bin/perl
# -------------------------------------------------------------------------
# Copyright (C) 2000-2017 TJ Saunders <tj@castaglia.org>
#
--- contrib/xferstats.holger-preiss
+++ contrib/xferstats.holger-preiss
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl
+#!/usr/bin/perl
# ---------------------------------------------------------------------------
#
# USAGE: xferstats <options>
--- src/prxs.in
+++ src/prxs.in
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl
+#!/usr/bin/perl

# ---------------------------------------------------------------------------
# Copyright (C) 2008-2012 TJ Saunders <tj@castaglia.org>

6
SOURCES/proftpd-welcome.msg

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@

*** Welcome to this anonymous ftp server! ***

You are user %N out of a maximum of %M authorized anonymous logins.
The current time here is %T.
If you experience any problems here, contact : %E

430
SOURCES/proftpd.conf

@ -0,0 +1,430 @@ @@ -0,0 +1,430 @@
# This is the ProFTPD configuration file
#
# See: http://www.proftpd.org/docs/directives/linked/by-name.html

# Security-Enhanced Linux (SELinux) Notes:
#
# In Fedora and Red Hat Enterprise Linux, ProFTPD runs confined by SELinux
# in order to mitigate the effects of an attacker taking advantage of an
# unpatched vulnerability and getting control of the ftp server. By default,
# ProFTPD cannot read or write most files on a system nor connect to many
# external network services, but these restrictions can be relaxed by
# setting SELinux booleans as follows:
#
# setsebool -P ftpd_anon_write=1
# This allows the ftp daemon to write to files and directories labelled
# with the public_content_rw_t context type; the daemon would only have
# read access to these files normally. Files to be made available by ftp
# but not writeable should be labelled public_content_t.
# On older systems this boolean was called allow_ftpd_anon_write.
#
# setsebool -P ftpd_full_access=1
# This allows the ftp daemon to read and write all files on the system.
# On older systems this boolean was called allow_ftpd_full_access, and there
# was a separate boolean ftp_home_dir to allow the ftp daemon access to
# files in users' home directories.
#
# setsebool -P ftpd_use_cifs=1
# This allows the ftp daemon to read and write files on CIFS-mounted
# filesystems.
# On older systems this boolean was called allow_ftpd_use_cifs.
#
# setsebool -P ftpd_use_fusefs=1
# This allows the ftp daemon to read and write files on ntfs/fusefs-mounted
# filesystems.
#
# setsebool -P ftpd_use_nfs=1
# This allows the ftp daemon to read and write files on NFS-mounted
# filesystems.
# On older systems this boolean was called allow_ftpd_use_nfs.
#
# setsebool -P ftpd_connect_all_unreserved=1
# This setting is only available from Fedora 16/RHEL-7 onwards, and is
# necessary for active-mode ftp transfers to work reliably with non-Linux
# clients (see http://bugzilla.redhat.com/782177), which may choose to
# use port numbers outside the "ephemeral port" range of 32768-61000.
#
# setsebool -P ftpd_connect_db=1
# This setting allows the ftp daemon to connect to commonly-used database
# ports over the network, which is necessary if you are using a database
# back-end for user authentication, etc.
#
# setsebool -P ftpd_use_passive_mode=1
# This setting allows the ftp daemon to bind to all unreserved ports for
# passive mode.
#
# All of these booleans are unset by default.
#
# See also the "ftpd_selinux" manpage.
#
# Note that the "-P" option to setsebool makes the setting permanent, i.e.
# it will still be in effect after a reboot; without the "-P" option, the
# effect only lasts until the next reboot.
#
# Restrictions imposed by SELinux are on top of those imposed by ordinary
# file ownership and access permissions; in normal operation, the ftp daemon
# will not be able to read and/or write a file unless *all* of the ownership,
# permission and SELinux restrictions allow it.

# Server Config - config used for anything outside a <VirtualHost> or <Global> context
# See: http://www.proftpd.org/docs/howto/Vhost.html

# Trace logging, disabled by default for performance reasons
# (http://www.proftpd.org/docs/howto/Tracing.html)
#TraceLog /var/log/proftpd/trace.log
#Trace DEFAULT:0

ServerName "ProFTPD server"
ServerIdent on "FTP Server ready."
ServerAdmin root@localhost
DefaultServer on

# Cause every FTP user except adm to be chrooted into their home directory
DefaultRoot ~ !adm

# Use pam to authenticate (default) and be authoritative
AuthPAMConfig proftpd
AuthOrder mod_auth_pam.c* mod_auth_unix.c
# If you use NIS/YP/LDAP you may need to disable PersistentPasswd
#PersistentPasswd off

# Don't do reverse DNS lookups (hangs on DNS problems)
UseReverseDNS off

# Set the user and group that the server runs as
User nobody
Group nobody

# To prevent DoS attacks, set the maximum number of child processes
# to 20. If you need to allow more than 20 concurrent connections
# at once, simply increase this value. Note that this ONLY works
# in standalone mode; in inetd mode you should use an inetd server
# that allows you to limit maximum number of processes per service
# (such as xinetd)
MaxInstances 20

# Disable sendfile by default since it breaks displaying the download speeds in
# ftptop and ftpwho
UseSendfile off

# Define the log formats
LogFormat default "%h %l %u %t \"%r\" %s %b"
LogFormat auth "%v [%P] %h %t \"%r\" %s"

# Dynamic Shared Object (DSO) loading
# See README.DSO and howto/DSO.html for more details
#
# 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
# (http://www.proftpd.org/docs/modules/mod_ctrls.html)
ControlsEngine on
ControlsACLs all allow user root
ControlsSocketACL allow user *
ControlsLog /var/log/proftpd/controls.log

# Enable admin controls via ftpdctl
# (http://www.proftpd.org/docs/contrib/mod_ctrls_admin.html)
<IfModule mod_ctrls_admin.c>
AdminControlsEngine on
AdminControlsACLs all allow user root
</IfModule>

# Enable mod_vroot by default for better compatibility with PAM
# (http://bugzilla.redhat.com/506735)
<IfModule mod_vroot.c>
VRootEngine on
</IfModule>

# TLS (http://www.castaglia.org/proftpd/modules/mod_tls.html)
<IfDefine TLS>
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=/var/run/proftpd/sesscache
</IfModule>
</IfDefine>

# 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
BanEngine on
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
# by the server (contrib/mod_qos.html)
<IfDefine QOS>
LoadModule mod_qos.c
# RFC791 TOS parameter compatibility
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
# See: http://www.proftpd.org/docs/howto/Vhost.html
<Global>

# Umask 022 is a good standard umask to prevent new dirs and files
# from being group and world writable
Umask 022

# Allow users to overwrite files and change permissions
AllowOverwrite yes
<Limit ALL SITE_CHMOD>
AllowAll
</Limit>

</Global>

# A basic anonymous configuration, with an upload directory
# Enable this with PROFTPD_OPTIONS=-DANONYMOUS_FTP in /etc/sysconfig/proftpd
<IfDefine ANONYMOUS_FTP>
<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>
</IfDefine>

13
SOURCES/proftpd.conf-no-memcached.patch

@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
--- proftpd.conf 2011-04-05 11:59:10.491108239 +0100
+++ proftpd.conf 2010-12-23 15:19:13.667374844 +0000
@@ -167,10 +167,6 @@
# (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)

12
SOURCES/proftpd.sysconfig

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
# Set PROFTPD_OPTIONS to add command-line options for proftpd.
# See proftpd(8) for a comprehensive list of what can be used.
#
# The following "Defines" can be used with the default configuration file:
# -DANONYMOUS_FTP : Enable anonymous FTP
# -DDYNAMIC_BAN_LISTS : Enable dynamic ban lists (mod_ban)
# -DQOS : Enable QoS bits on server traffic (mod_qos)
# -DTLS : Enable TLS (mod_tls)
#
# For example, for anonymous FTP and dynamic ban list support:
# PROFTPD_OPTIONS="-DANONYMOUS_FTP -DDYNAMIC_BAN_LISTS"
PROFTPD_OPTIONS=""

1602
SPECS/proftpd.spec

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save