From 060da19d809b133fb322d27a15573028cf11e4b9 Mon Sep 17 00:00:00 2001 From: Paul Howarth Date: Dec 24 2010 12:50:57 +0000 Subject: Update to 1.3.4rc1 New upstream release 1.3.4rc1 (see RELEASE_NOTES for full details) - Added Japanese translation - Many mod_sftp bugfixes - Fixed SSL_shutdown() errors caused by OpenSSL 0.9.8m and later - Added support for SMTP authentication in ftpmail script - Updated fnmatch implementation, using glibc-2.9 version - New modules: mod_copy, mod_deflate, mod_ifversion, mod_qos - New configuration directives: - Protocols - ScoreboardMutex - SFTPClientAlive - WrapOptions - Changed configuration directives: - BanOnEvent - ListOptions - LogFormat - SFTPOptions - TLSOptions - UseSendfile - Deprecated configuration directives: - DisplayGoAway (support for this directive has been removed) Add %check section, running the API tests by default BR: check-devel, needed for the API test suite Add upstream patch (http://bugs.proftpd.org/3568), modified slightly, to fix the API tests Optionally run the perl-based integration test suite if the build option --with integrationtests is supplied; this is off by default as it is not fully maintained and is expected to fail in parts (see http://bugs.proftpd.org/3568#c5) Bundle perl(Test::Unit) 0.14, needed to run the integration test suite (version in Fedora is incompatible later version not from CPAN) BR: perl modules Compress::Zlib, IO::Socket::SSL, Net::FTPSSL, Net::SSLeay, Net::Telnet, Test::Harness and Time::HiRes if building --with integrationtests New DSO modules: mod_copy, mod_deflate, mod_ifversion, mod_qos QoS support can be enabled in /etc/sysconfig/proftpd --- diff --git a/.gitignore b/.gitignore index 8f3eef9..96137a1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ -/proftpd-1.3.3d.tar.bz2 +/proftpd-1.3.4rc1.tar.bz2 /proftpd-mod-geoip-0.2.tar.gz /proftpd-mod-vroot-0.9.tar.gz +/Test-Unit-0.14.tar.gz diff --git a/proftpd-1.3.4rc1-tests.patch b/proftpd-1.3.4rc1-tests.patch new file mode 100644 index 0000000..2c8409b --- /dev/null +++ b/proftpd-1.3.4rc1-tests.patch @@ -0,0 +1,954 @@ +diff -up proftpd-1.3.4rc1/src/scoreboard.c.tests proftpd-1.3.4rc1/src/scoreboard.c +--- proftpd-1.3.4rc1/src/scoreboard.c.tests 2010-11-16 15:46:23.000000000 +0000 ++++ proftpd-1.3.4rc1/src/scoreboard.c 2010-12-21 22:01:57.177572723 +0000 +@@ -392,7 +392,19 @@ void pr_delete_scoreboard(void) { + } + } + ++ if (scoreboard_mutex_fd > -1) { ++ while (close(scoreboard_mutex_fd) < 0) { ++ if (errno == EINTR) { ++ pr_signals_handle(); ++ continue; ++ } ++ ++ break; ++ } ++ } ++ + scoreboard_fd = -1; ++ scoreboard_mutex_fd = -1; + scoreboard_opener = 0; + + if (*scoreboard_file) { +@@ -406,6 +418,17 @@ void pr_delete_scoreboard(void) { + (void) unlink(scoreboard_file); + (void) unlink(scoreboard_mutex); + } ++ ++ if (*scoreboard_mutex) { ++ struct stat st; ++ ++ if (stat(scoreboard_mutex, &st) == 0) { ++ pr_log_debug(DEBUG3, "deleting existing scoreboard mutex '%s'", ++ scoreboard_mutex); ++ } ++ ++ (void) unlink(scoreboard_mutex); ++ } + } + + const char *pr_get_scoreboard(void) { +diff -up proftpd-1.3.4rc1/tests/api/scoreboard.c.tests proftpd-1.3.4rc1/tests/api/scoreboard.c +--- proftpd-1.3.4rc1/tests/api/scoreboard.c.tests 2010-03-04 17:29:08.000000000 +0000 ++++ proftpd-1.3.4rc1/tests/api/scoreboard.c 2010-12-21 21:34:47.427708792 +0000 +@@ -131,6 +131,7 @@ END_TEST + START_TEST (scoreboard_open_close_test) { + int res; + const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test", ++ *mutex_path = "/tmp/prt-scoreboard/test.lck", + *symlink_path = "/tmp/prt-scoreboard/symlink"; + + res = mkdir(dir, 0775); +@@ -154,12 +155,14 @@ START_TEST (scoreboard_open_close_test) + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + + if (symlink(symlink_path, path) == 0) { + + res = pr_open_scoreboard(O_RDWR); + if (res == 0) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) unlink(symlink_path); + (void) rmdir(dir); + +@@ -170,6 +173,7 @@ START_TEST (scoreboard_open_close_test) + int xerrno = errno; + + (void) unlink(symlink_path); ++ (void) unlink(mutex_path); + (void) unlink(path); + (void) rmdir(dir); + +@@ -177,12 +181,14 @@ START_TEST (scoreboard_open_close_test) + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) unlink(symlink_path); + } + + res = pr_open_scoreboard(O_RDONLY); + if (res == 0) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly opened scoreboard using O_RDONLY"); +@@ -192,6 +198,7 @@ START_TEST (scoreboard_open_close_test) + int xerrno = errno; + + (void) unlink(symlink_path); ++ (void) unlink(mutex_path); + (void) unlink(path); + (void) rmdir(dir); + +@@ -202,6 +209,7 @@ START_TEST (scoreboard_open_close_test) + if (res < 0) { + int xerrno = errno; + ++ (void) unlink(mutex_path); + (void) unlink(path); + (void) rmdir(dir); + +@@ -213,6 +221,7 @@ START_TEST (scoreboard_open_close_test) + + res = pr_open_scoreboard(O_RDONLY); + if (res == 0) { ++ (void) unlink(mutex_path); + (void) unlink(path); + (void) rmdir(dir); + +@@ -222,12 +231,14 @@ START_TEST (scoreboard_open_close_test) + if (errno != EINVAL) { + int xerrno = errno; + ++ (void) unlink(mutex_path); + (void) unlink(path); + (void) rmdir(dir); + + fail("Failed to set errno to EINVAL (got %d)", xerrno); + } + ++ (void) unlink(mutex_path); + (void) unlink(path); + (void) rmdir(dir); + } +@@ -235,7 +246,8 @@ END_TEST + + START_TEST (scoreboard_delete_test) { + int res; +- const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test"; ++ const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test", ++ *mutex_path = "/tmp/prt-scoreboard/test.lck"; + struct stat st; + + res = mkdir(dir, 0775); +@@ -259,11 +271,13 @@ START_TEST (scoreboard_delete_test) { + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + + res = pr_open_scoreboard(O_RDWR); + if (res < 0) { + int xerrno = errno; + ++ (void) unlink(mutex_path); + (void) unlink(path); + (void) rmdir(dir); + +@@ -274,6 +288,7 @@ START_TEST (scoreboard_delete_test) { + if (res < 0) { + int xerrno = errno; + ++ (void) unlink(mutex_path); + (void) unlink(path); + (void) rmdir(dir); + +@@ -285,19 +300,31 @@ START_TEST (scoreboard_delete_test) { + res = stat(pr_get_scoreboard(), &st); + if (res == 0) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly found deleted scoreboard"); + } + ++ res = stat(pr_get_scoreboard_mutex(), &st); ++ if (res == 0) { ++ (void) unlink(path); ++ (void) unlink(mutex_path); ++ (void) rmdir(dir); ++ ++ fail("Unexpectedly found deleted scoreboard mutex"); ++ } ++ + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + } + END_TEST + + START_TEST (scoreboard_restore_test) { + int res; +- const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test"; ++ const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test", ++ *mutex_path = "/tmp/prt-scoreboard/test.lck"; + + res = mkdir(dir, 0775); + fail_unless(res == 0, "Failed to create directory '%s': %s", dir, +@@ -320,10 +347,12 @@ START_TEST (scoreboard_restore_test) { + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + + res = pr_restore_scoreboard(); + if (res == 0) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly restored scoreboard"); +@@ -333,6 +362,7 @@ START_TEST (scoreboard_restore_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to set errno to EINVAL (got %d)", xerrno); +@@ -343,6 +373,7 @@ START_TEST (scoreboard_restore_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to open scoreboard: %s", strerror(xerrno)); +@@ -353,19 +384,22 @@ START_TEST (scoreboard_restore_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to restore scoreboard: %s", strerror(xerrno)); + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + } + END_TEST + + START_TEST (scoreboard_rewind_test) { + int res; +- const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test"; ++ const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test", ++ *mutex_path = "/tmp/prt-scoreboard/test.lck"; + + res = mkdir(dir, 0775); + fail_unless(res == 0, "Failed to create directory '%s': %s", dir, +@@ -388,10 +422,12 @@ START_TEST (scoreboard_rewind_test) { + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + + res = pr_rewind_scoreboard(); + if (res == 0) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly rewound scoreboard"); +@@ -401,6 +437,7 @@ START_TEST (scoreboard_rewind_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to set errno to EINVAL (got %d)", xerrno); +@@ -411,6 +448,7 @@ START_TEST (scoreboard_rewind_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to open scoreboard: %s", strerror(xerrno)); +@@ -421,12 +459,14 @@ START_TEST (scoreboard_rewind_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to rewind scoreboard: %s", strerror(xerrno)); + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + } + END_TEST +@@ -434,7 +474,8 @@ END_TEST + START_TEST (scoreboard_scrub_test) { + uid_t euid; + int res; +- const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test"; ++ const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test", ++ *mutex_path = "/tmp/prt-scoreboard/test.lck"; + + res = mkdir(dir, 0775); + fail_unless(res == 0, "Failed to create directory '%s': %s", dir, +@@ -457,10 +498,12 @@ START_TEST (scoreboard_scrub_test) { + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + + res = pr_scoreboard_scrub(); + if (res == 0) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly scrubbed scoreboard"); +@@ -472,6 +515,7 @@ START_TEST (scoreboard_scrub_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to set errno to EPERM, got %d (euid = %lu)", xerrno, +@@ -483,6 +527,7 @@ START_TEST (scoreboard_scrub_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to set errno to ENOENT, got %d (euid = %lu)", xerrno, +@@ -495,6 +540,7 @@ START_TEST (scoreboard_scrub_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to open scoreboard: %s", strerror(xerrno)); +@@ -505,19 +551,22 @@ START_TEST (scoreboard_scrub_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to scrub scoreboard: %s", strerror(xerrno)); + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + } + END_TEST + + START_TEST (scoreboard_get_daemon_pid_test) { + int res; +- const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test"; ++ const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test", ++ *mutex_path = "/tmp/prt-scoreboard/test.lck"; + pid_t daemon_pid; + + res = mkdir(dir, 0775); +@@ -541,12 +590,14 @@ START_TEST (scoreboard_get_daemon_pid_te + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + + res = pr_open_scoreboard(O_RDWR); + if (res < 0) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to open scoreboard: %s", strerror(xerrno)); +@@ -555,6 +606,7 @@ START_TEST (scoreboard_get_daemon_pid_te + daemon_pid = pr_scoreboard_get_daemon_pid(); + if (daemon_pid != getpid()) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Expected %lu, got %lu", (unsigned long) getpid(), +@@ -570,6 +622,7 @@ START_TEST (scoreboard_get_daemon_pid_te + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to open scoreboard: %s", strerror(xerrno)); +@@ -578,6 +631,7 @@ START_TEST (scoreboard_get_daemon_pid_te + daemon_pid = pr_scoreboard_get_daemon_pid(); + if (daemon_pid != 0) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Expected %lu, got %lu", (unsigned long) 0, +@@ -585,13 +639,15 @@ START_TEST (scoreboard_get_daemon_pid_te + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + } + END_TEST + + START_TEST (scoreboard_get_daemon_uptime_test) { + int res; +- const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test"; ++ const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test", ++ *mutex_path = "/tmp/prt-scoreboard/test.lck"; + time_t daemon_uptime, now; + + res = mkdir(dir, 0775); +@@ -615,12 +671,14 @@ START_TEST (scoreboard_get_daemon_uptime + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + + res = pr_open_scoreboard(O_RDWR); + if (res < 0) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to open scoreboard: %s", strerror(xerrno)); +@@ -631,6 +689,7 @@ START_TEST (scoreboard_get_daemon_uptime + + if (daemon_uptime > now) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Expected %lu, got %lu", (unsigned long) now, +@@ -646,6 +705,7 @@ START_TEST (scoreboard_get_daemon_uptime + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to open scoreboard: %s", strerror(xerrno)); +@@ -654,6 +714,7 @@ START_TEST (scoreboard_get_daemon_uptime + daemon_uptime = pr_scoreboard_get_daemon_uptime(); + if (daemon_uptime != 0) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Expected %lu, got %lu", (unsigned long) 0, +@@ -661,13 +722,15 @@ START_TEST (scoreboard_get_daemon_uptime + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + } + END_TEST + + START_TEST (scoreboard_entry_add_test) { + int res; +- const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test"; ++ const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test", ++ *mutex_path = "/tmp/prt-scoreboard/test.lck"; + + res = mkdir(dir, 0775); + fail_unless(res == 0, "Failed to create directory '%s': %s", dir, +@@ -690,10 +753,12 @@ START_TEST (scoreboard_entry_add_test) { + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + + res = pr_scoreboard_entry_add(); + if (res == 0) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly added entry to scoreboard"); +@@ -703,6 +768,7 @@ START_TEST (scoreboard_entry_add_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to set errno to EINVAL (got %d)", xerrno); +@@ -713,6 +779,7 @@ START_TEST (scoreboard_entry_add_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to open scoreboard: %s", strerror(xerrno)); +@@ -723,6 +790,7 @@ START_TEST (scoreboard_entry_add_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to add entry to scoreboard: %s", strerror(xerrno)); +@@ -731,6 +799,7 @@ START_TEST (scoreboard_entry_add_test) { + res = pr_scoreboard_entry_add(); + if (res == 0) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly added entry to scoreboard"); +@@ -740,19 +809,22 @@ START_TEST (scoreboard_entry_add_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to set errno to EPERM (got %d)", xerrno); + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + } + END_TEST + + START_TEST (scoreboard_entry_del_test) { + int res; +- const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test"; ++ const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test", ++ *mutex_path = "/tmp/prt-scoreboard/test.lck"; + + res = mkdir(dir, 0775); + fail_unless(res == 0, "Failed to create directory '%s': %s", dir, +@@ -775,10 +847,12 @@ START_TEST (scoreboard_entry_del_test) { + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + + res = pr_scoreboard_entry_del(FALSE); + if (res == 0) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly deleted entry from scoreboard"); +@@ -788,6 +862,7 @@ START_TEST (scoreboard_entry_del_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to set errno to EINVAL (got %d)", xerrno); +@@ -798,6 +873,7 @@ START_TEST (scoreboard_entry_del_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to open scoreboard: %s", strerror(xerrno)); +@@ -806,6 +882,7 @@ START_TEST (scoreboard_entry_del_test) { + res = pr_scoreboard_entry_del(FALSE); + if (res == 0) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly deleted entry from scoreboard"); +@@ -815,6 +892,7 @@ START_TEST (scoreboard_entry_del_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to set errno to ENOENT (got %d)", xerrno); +@@ -825,6 +903,7 @@ START_TEST (scoreboard_entry_del_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to add entry to scoreboard: %s", strerror(xerrno)); +@@ -835,6 +914,7 @@ START_TEST (scoreboard_entry_del_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to delete entry from scoreboard: %s", strerror(xerrno)); +@@ -843,6 +923,7 @@ START_TEST (scoreboard_entry_del_test) { + res = pr_scoreboard_entry_del(FALSE); + if (res == 0) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly deleted entry from scoreboard"); +@@ -852,19 +933,22 @@ START_TEST (scoreboard_entry_del_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to set errno to ENOENT (got %d)", xerrno); + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + } + END_TEST + + START_TEST (scoreboard_entry_read_test) { + int res; +- const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test"; ++ const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test", ++ *mutex_path = "/tmp/prt-scoreboard/test.lck"; + pr_scoreboard_entry_t *score; + + res = mkdir(dir, 0775); +@@ -888,10 +972,12 @@ START_TEST (scoreboard_entry_read_test) + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + + score = pr_scoreboard_entry_read(); + if (score != NULL) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly read scoreboard entry"); +@@ -901,6 +987,7 @@ START_TEST (scoreboard_entry_read_test) + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to set errno to EINVAL (got %d)", xerrno); +@@ -911,6 +998,7 @@ START_TEST (scoreboard_entry_read_test) + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to open scoreboard: %s", strerror(xerrno)); +@@ -920,6 +1008,7 @@ START_TEST (scoreboard_entry_read_test) + score = pr_scoreboard_entry_read(); + if (score != NULL) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly read scoreboard entry"); +@@ -930,6 +1019,7 @@ START_TEST (scoreboard_entry_read_test) + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to add entry to scoreboard: %s", strerror(xerrno)); +@@ -940,6 +1030,7 @@ START_TEST (scoreboard_entry_read_test) + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to read scoreboard entry: %s", strerror(xerrno)); +@@ -947,6 +1038,7 @@ START_TEST (scoreboard_entry_read_test) + + if (score->sce_pid != getpid()) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to read expected scoreboard entry (expected PID %lu, got %lu)", +@@ -956,19 +1048,22 @@ START_TEST (scoreboard_entry_read_test) + score = pr_scoreboard_entry_read(); + if (score != NULL) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly read scoreboard entry"); + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + } + END_TEST + + START_TEST (scoreboard_entry_get_test) { + int res; +- const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test"; ++ const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test", ++ *mutex_path = "/tmp/prt-scoreboard/test.lck"; + const char *val; + + res = mkdir(dir, 0775); +@@ -992,10 +1087,12 @@ START_TEST (scoreboard_entry_get_test) { + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + + val = pr_scoreboard_entry_get(-1); + if (val != NULL) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly read value from scoreboard entry"); +@@ -1005,6 +1102,7 @@ START_TEST (scoreboard_entry_get_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to set errno to EINVAL (got %d)", xerrno); +@@ -1015,6 +1113,7 @@ START_TEST (scoreboard_entry_get_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to open scoreboard: %s", strerror(xerrno)); +@@ -1023,6 +1122,7 @@ START_TEST (scoreboard_entry_get_test) { + val = pr_scoreboard_entry_get(-1); + if (val != NULL) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly read value from scoreboard entry"); +@@ -1032,6 +1132,7 @@ START_TEST (scoreboard_entry_get_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to set errno to EPERM (got %d)", xerrno); +@@ -1042,6 +1143,7 @@ START_TEST (scoreboard_entry_get_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to add entry to scoreboard: %s", strerror(xerrno)); +@@ -1050,6 +1152,7 @@ START_TEST (scoreboard_entry_get_test) { + val = pr_scoreboard_entry_get(-1); + if (val != NULL) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly read value from scoreboard entry"); +@@ -1059,12 +1162,14 @@ START_TEST (scoreboard_entry_get_test) { + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to set errno to ENOENT (got %d)", xerrno); + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + } + END_TEST +@@ -1072,7 +1177,8 @@ END_TEST + START_TEST (scoreboard_entry_update_test) { + int res; + const char *val; +- const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test"; ++ const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test", ++ *mutex_path = "/tmp/prt-scoreboard/test.lck"; + pid_t pid = getpid(); + + res = mkdir(dir, 0775); +@@ -1096,10 +1202,12 @@ START_TEST (scoreboard_entry_update_test + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + + res = pr_scoreboard_entry_update(pid, 0); + if (res == 0) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly updated scoreboard entry"); +@@ -1109,6 +1217,7 @@ START_TEST (scoreboard_entry_update_test + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to set errno to EINVAL (got %d)", xerrno); +@@ -1119,6 +1228,7 @@ START_TEST (scoreboard_entry_update_test + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to open scoreboard: %s", strerror(xerrno)); +@@ -1127,6 +1237,7 @@ START_TEST (scoreboard_entry_update_test + res = pr_scoreboard_entry_update(pid, 0); + if (res == 0) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly updated scoreboard entry"); +@@ -1136,6 +1247,7 @@ START_TEST (scoreboard_entry_update_test + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to set errno to EPERM (got %d)", xerrno); +@@ -1146,6 +1258,7 @@ START_TEST (scoreboard_entry_update_test + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to add entry to scoreboard: %s", strerror(xerrno)); +@@ -1154,6 +1267,7 @@ START_TEST (scoreboard_entry_update_test + res = pr_scoreboard_entry_update(pid, -1); + if (res == 0) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Unexpectedly updated scoreboard entry"); +@@ -1163,6 +1277,7 @@ START_TEST (scoreboard_entry_update_test + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to set errno to ENOENT (got %d)", xerrno); +@@ -1174,6 +1289,7 @@ START_TEST (scoreboard_entry_update_test + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to update PR_SCORE_CWD: %s", strerror(xerrno)); +@@ -1184,6 +1300,7 @@ START_TEST (scoreboard_entry_update_test + int xerrno = errno; + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Failed to get entry PR_SCORE_CWD: %s", strerror(xerrno)); +@@ -1191,12 +1308,14 @@ START_TEST (scoreboard_entry_update_test + + if (strcmp(val, "cwd") != 0) { + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + + fail("Expected '%s', got '%s'", "cwd", val); + } + + (void) unlink(path); ++ (void) unlink(mutex_path); + (void) rmdir(dir); + } + END_TEST +diff -up proftpd-1.3.4rc1/tests/api/stubs.c.tests proftpd-1.3.4rc1/tests/api/stubs.c +--- proftpd-1.3.4rc1/tests/api/stubs.c.tests 2008-10-06 19:16:50.000000000 +0100 ++++ proftpd-1.3.4rc1/tests/api/stubs.c 2010-12-21 21:34:47.428708819 +0000 +@@ -34,6 +34,10 @@ server_rec *main_server = NULL; + module *static_modules[] = { NULL }; + module *loaded_modules = NULL; + ++int pr_ctrls_unregister(module *m, const char *action) { ++ return 0; ++} ++ + void pr_log_debug(int level, const char *fmt, ...) { + } + +diff -up proftpd-1.3.4rc1/tests/api/pool.c.tests proftpd-1.3.4rc1/tests/api/pool.c +--- proftpd-1.3.4rc1/tests/api/pool.c.tests 2009-01-30 00:14:16.000000000 +0000 ++++ proftpd-1.3.4rc1/tests/api/pool.c 2010-12-23 13:32:48.022565092 +0000 +@@ -116,7 +116,7 @@ + fail_unless(v == NULL, "Allocated %u-len memory", sz); + + sz = 1; +- v = palloc(p, sz); ++ v = pcalloc(p, sz); + fail_if(v == NULL, "Failed to allocate %u-len memory", sz); + for (i = 0; i < sz; i++) { + fail_unless(v[i] == 0, "Allocated non-zero memory at position %u", i); +diff -up proftpd-1.3.4rc1/tests/api/timers.c.tests proftpd-1.3.4rc1/tests/api/timers.c +--- proftpd-1.3.4rc1/tests/api/timers.c.tests 2010-08-11 15:56:36.000000000 +0100 ++++ proftpd-1.3.4rc1/tests/api/timers.c 2010-12-24 11:03:17.625550991 +0000 +@@ -121,7 +121,7 @@ + timers_handle_signals(); + + ok = 2; +- fail_unless(timer_triggered_count == ok, ++ fail_unless(timer_triggered_count == ok || timer_triggered_count == ok + 1, + "Timer failed to fire (expected count %u, got %u)", ok, + timer_triggered_count); + +@@ -129,7 +129,7 @@ + timers_handle_signals(); + + ok = 3; +- fail_unless(timer_triggered_count == ok, ++ fail_unless(timer_triggered_count == ok || timer_triggered_count == ok + 1, + "Timer failed to fire (expected count %u, got %u)", ok, + timer_triggered_count); + } diff --git a/proftpd.conf b/proftpd.conf index 736f610..ffe4614 100644 --- a/proftpd.conf +++ b/proftpd.conf @@ -91,10 +91,21 @@ LogFormat auth "%v [%P] %h %t \"%r\" %s" # (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) @@ -109,6 +120,12 @@ LogFormat auth "%v [%P] %h %t \"%r\" %s" # (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 @@ -204,6 +221,16 @@ LogFormat auth "%v [%P] %h %t \"%r\" %s" BanControlsACLs all allow user ftpadm +# Set networking-specific "Quality of Service" (QoS) bits on the packets used +# by the server (contrib/mod_qos.html) + + 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 + + # Global Config - config common to Server Config and all virtual hosts # See: http://www.proftpd.org/docs/howto/Vhost.html diff --git a/proftpd.spec b/proftpd.spec index 92d42f9..8361a9e 100644 --- a/proftpd.spec +++ b/proftpd.spec @@ -1,3 +1,8 @@ +# +# Rebuild switch: +# --with integrationtests enable integration tests (not fully maintained, may fail) +# + # Use certs in %%{_sysconfdir}/pki/tls/certs if available (FC4, RHEL5 onwards) %global use_pki %(if [ -d %{_sysconfdir}/pki/tls/certs ]; then echo 1; else echo 0; fi) %if %{use_pki} @@ -6,12 +11,12 @@ %global pkidir %{_datadir}/ssl %endif -#global prever rc4 +%global prever rc1 %global rpmrel 1 Summary: Flexible, stable and highly-configurable FTP server Name: proftpd -Version: 1.3.3d +Version: 1.3.4 Release: %{?prever:0.}%{rpmrel}%{?prever:.%{prever}}%{?dist} License: GPLv2+ Group: System Environment/Daemons @@ -29,7 +34,14 @@ Source9: proftpd.sysconfig Source10: http://www.castaglia.org/proftpd/modules/proftpd-mod-vroot-0.9.tar.gz Source11: http://www.castaglia.org/proftpd/modules/proftpd-mod-geoip-0.2.tar.gz Source12: proftpd-tmpfs.conf +# The integration tests require perl(Test::Unit) 0.14, which is the latest release on CPAN +# However, the version in Fedora is 0.25 from sourceforge, which is incompatible with the test suite, +# so we bundle version 0.14 here, purely for use during builds with the integration tests enabled +# (they are disabled by default); it is not included as part of the built package and should therefore +# not fall foul of the rules against library bundling +Source13: http://search.cpan.org/CPAN/authors/id/C/CL/CLEMBURG/Test-Unit-0.14.tar.gz Patch0: proftpd-1.3.2rc3-nostrip.patch +Patch1: proftpd-1.3.4rc1-tests.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root Requires(post): /sbin/chkconfig Requires(preun): /sbin/service, /sbin/chkconfig, coreutils, findutils @@ -41,6 +53,19 @@ Requires: systemd-units BuildRequires: pam-devel, ncurses-devel, pkgconfig, gettext, zlib-devel BuildRequires: openssl-devel, libacl-devel, libcap-devel, /usr/include/tcpd.h BuildRequires: openldap-devel, mysql-devel, postgresql-devel, GeoIP-devel + +# Test suite requirements +BuildRequires: check-devel +%if 0%{?_with_integrationtests:1} +BuildRequires: perl(Compress::Zlib) +BuildRequires: perl(IO::Socket::SSL) +BuildRequires: perl(Net::FTPSSL) +BuildRequires: perl(Net::SSLeay) +BuildRequires: perl(Net::Telnet) +BuildRequires: perl(Test::Harness) +BuildRequires: perl(Time::HiRes) +%endif + Provides: ftpserver %description @@ -78,7 +103,7 @@ Requires: %{name} = %{version}-%{release} Module to add PostgreSQL support to the ProFTPD FTP server. %prep -%setup -q -n %{name}-%{version}%{?prever} -a 10 -a 11 +%setup -q -n %{name}-%{version}%{?prever} -a 10 -a 11 -a 13 # Copy mod_vroot source and documentation into place %{__cp} -p mod_vroot/mod_vroot.c contrib/ @@ -91,6 +116,9 @@ Module to add PostgreSQL support to the ProFTPD FTP server. # Don't strip binaries - needed for useful debuginfo %patch0 -p1 -b .nostrip +# Upstream patch (http://bugs.proftpd.org/3568), modified slightly, to fix the API tests +%patch1 -p1 -b .tests + # Avoid documentation name conflicts %{__mv} contrib/README contrib/README.contrib @@ -137,7 +165,7 @@ SMOD1=mod_sql:mod_sql_passwd:mod_sql_mysql:mod_sql_postgres SMOD2=mod_quotatab:mod_quotatab_file:mod_quotatab_ldap:mod_quotatab_radius:mod_quotatab_sql SMOD3=mod_ldap:mod_ban:mod_wrap:mod_ctrls_admin:mod_facl:mod_load SMOD4=mod_radius:mod_ratio:mod_rewrite:mod_site_misc:mod_exec:mod_shaper:mod_geoip -SMOD5=mod_wrap2:mod_wrap2_file:mod_wrap2_sql +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 %configure \ @@ -150,6 +178,7 @@ SMOD6=mod_sftp:mod_sftp_pam:mod_sftp_sql:mod_tls_shmcache --enable-nls \ --enable-openssl \ --enable-shadow \ + --enable-tests \ --with-libraries="%{_libdir}/mysql" \ --with-includes="%{_includedir}/mysql" \ --with-modules=mod_readme:mod_auth_pam:mod_tls:mod_vroot \ @@ -183,6 +212,22 @@ SMOD6=mod_sftp:mod_sftp_pam:mod_sftp_sql:mod_tls_shmcache # Find translations %find_lang proftpd +%check +# Integration tests not fully maintained - stick to API tests only by default +%if 0%{?_with_integrationtests:1} +export PERL5LIB=$(pwd)/Test-Unit-0.14/lib +%{__make} check +%else +# API tests should always be OK +if ! %{__make} -C tests api-tests; then + # Diagnostics to report upstream + cat tests/api-tests.log + ./proftpd -V + # Fail the build + false +fi +%endif + %clean %{__rm} -rf %{buildroot} @@ -256,11 +301,15 @@ fi %dir %{_libexecdir}/proftpd/ %{_libexecdir}/proftpd/mod_ban.so %{_libexecdir}/proftpd/mod_ctrls_admin.so +%{_libexecdir}/proftpd/mod_copy.so +%{_libexecdir}/proftpd/mod_deflate.so %{_libexecdir}/proftpd/mod_exec.so %{_libexecdir}/proftpd/mod_facl.so %{_libexecdir}/proftpd/mod_geoip.so %{_libexecdir}/proftpd/mod_ifsession.so +%{_libexecdir}/proftpd/mod_ifversion.so %{_libexecdir}/proftpd/mod_load.so +%{_libexecdir}/proftpd/mod_qos.so %{_libexecdir}/proftpd/mod_quotatab.so %{_libexecdir}/proftpd/mod_quotatab_file.so %{_libexecdir}/proftpd/mod_quotatab_radius.so @@ -300,6 +349,43 @@ fi %{_libexecdir}/proftpd/mod_sql_postgres.so %changelog +* Fri Dec 24 2010 Paul Howarth 1.3.4-0.1.rc1 +- Update to 1.3.4rc1 (see RELEASE_NOTES for full details) + - Added Japanese translation + - Many mod_sftp bugfixes + - Fixed SSL_shutdown() errors caused by OpenSSL 0.9.8m and later + - Added support for SMTP authentication in ftpmail script + - Updated fnmatch implementation, using glibc-2.9 version + - New modules: mod_copy, mod_deflate, mod_ifversion, mod_qos + - New configuration directives: + - Protocols + - ScoreboardMutex + - SFTPClientAlive + - WrapOptions + - Changed configuration directives: + - BanOnEvent + - ListOptions + - LogFormat + - SFTPOptions + - TLSOptions + - UseSendfile + - Deprecated configuration directives: + - DisplayGoAway (support for this directive has been removed) +- Add %%check section, running the API tests by default +- BR: check-devel, needed for the API test suite +- Add upstream patch (http://bugs.proftpd.org/3568), modified slightly, to fix + the API tests +- Optionally run the perl-based integration test suite if the build option + --with integrationtests is supplied; this is off by default as it is not + fully maintained and is expected to fail in parts + (see http://bugs.proftpd.org/3568#c5) +- Bundle perl(Test::Unit) 0.14, needed to run the integration test suite + (version in Fedora is incompatible later version not from CPAN) +- BR: perl modules Compress::Zlib, IO::Socket::SSL, Net::FTPSSL, Net::SSLeay, + Net::Telnet, Test::Harness and Time::HiRes if building --with integrationtests +- New DSO modules: mod_copy, mod_deflate, mod_ifversion, mod_qos +- QoS support can be enabled in /etc/sysconfig/proftpd + * Mon Dec 20 2010 Paul Howarth 1.3.3d-1 - Update to 1.3.3d - Fixed sql_prepare_where() buffer overflow (bug 3536) diff --git a/proftpd.sysconfig b/proftpd.sysconfig index aa7ac11..fcef206 100644 --- a/proftpd.sysconfig +++ b/proftpd.sysconfig @@ -4,6 +4,7 @@ # 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: diff --git a/sources b/sources index f5f4bf4..a9e2c08 100644 --- a/sources +++ b/sources @@ -1,3 +1,4 @@ -69650e91e05b3a10fa3ac54ee261679b proftpd-1.3.3d.tar.bz2 +3472f7a8fb760f549daf485642277024 proftpd-1.3.4rc1.tar.bz2 6242218c0c98efbab8076ec3bc9fd4d5 proftpd-mod-geoip-0.2.tar.gz 181669582a2cf5d54f0df15a4d83eae6 proftpd-mod-vroot-0.9.tar.gz +ad574713bcd00f62883ff2f9a84eec1f Test-Unit-0.14.tar.gz