diff --git a/SOURCES/vsftpd-2.2.2-blank-chars-overflow.patch b/SOURCES/vsftpd-2.2.2-blank-chars-overflow.patch new file mode 100644 index 0000000..067f7fe --- /dev/null +++ b/SOURCES/vsftpd-2.2.2-blank-chars-overflow.patch @@ -0,0 +1,13 @@ +diff --git a/str.c b/str.c +index 41b27db..82b8ae4 100644 +--- a/str.c ++++ b/str.c +@@ -113,7 +113,7 @@ str_strdup_trimmed(const struct mystr* p_str) + for (h = 0; h < (int)str_getlen(p_str) && vsf_sysutil_isspace(p_trimmed[h]); h++) ; + for (t = str_getlen(p_str) - 1; t >= 0 && vsf_sysutil_isspace(p_trimmed[t]); t--) ; + newlen = t - h + 1; +- return newlen ? vsf_sysutil_strndup(p_trimmed+h, (unsigned int)newlen) : 0L; ++ return (newlen > 0) ? vsf_sysutil_strndup(p_trimmed+h, (unsigned int)newlen) : 0L; + } + + void diff --git a/SOURCES/vsftpd-2.2.2-man-pages.patch b/SOURCES/vsftpd-2.2.2-man-pages.patch new file mode 100644 index 0000000..87b2405 --- /dev/null +++ b/SOURCES/vsftpd-2.2.2-man-pages.patch @@ -0,0 +1,14 @@ +diff --git a/vsftpd.conf.5 b/vsftpd.conf.5 +index 721b325..868ec94 100644 +--- a/vsftpd.conf.5 ++++ b/vsftpd.conf.5 +@@ -478,7 +478,8 @@ Default: NO + .TP + .B ssl_request_cert + If enabled, vsftpd will request (but not necessarily require; see +-.BR require_cert) a certificate on incoming SSL connections. Normally this ++.BR require_cert ) ++a certificate on incoming SSL connections. Normally this + should not cause any trouble at all, but IBM zOS seems to have issues. + (New in v2.0.7). + diff --git a/SOURCES/vsftpd-2.2.2-nfs-fail.patch b/SOURCES/vsftpd-2.2.2-nfs-fail.patch new file mode 100644 index 0000000..1439275 --- /dev/null +++ b/SOURCES/vsftpd-2.2.2-nfs-fail.patch @@ -0,0 +1,129 @@ +diff --git a/ftpcodes.h b/ftpcodes.h +index 995788a..22c3c9b 100644 +--- a/ftpcodes.h ++++ b/ftpcodes.h +@@ -73,6 +73,7 @@ + #define FTP_NOHANDLEPROT 536 + #define FTP_FILEFAIL 550 + #define FTP_NOPERM 550 ++#define FTP_DISKQUOTA 552 + #define FTP_UPLOADFAIL 553 + + #endif /* VSF_FTPCODES_H */ +diff --git a/postlogin.c b/postlogin.c +index e1f080f..ffe0f38 100644 +--- a/postlogin.c ++++ b/postlogin.c +@@ -28,6 +28,8 @@ + #include "vsftpver.h" + #include "opts.h" + ++#include ++ + /* Private local functions */ + static void handle_pwd(struct vsf_session* p_sess); + static void handle_cwd(struct vsf_session* p_sess); +@@ -996,8 +998,10 @@ handle_upload_common(struct vsf_session* p_sess, int is_append, int is_unique) + struct vsf_transfer_ret trans_ret; + int new_file_fd; + int remote_fd; ++ int close_errno; + int success = 0; + int created = 0; ++ int closed = 0; + int do_truncate = 0; + filesize_t offset = p_sess->restart_pos; + p_sess->restart_pos = 0; +@@ -1110,6 +1114,18 @@ handle_upload_common(struct vsf_session* p_sess, int is_append, int is_unique) + trans_ret = vsf_ftpdataio_transfer_file(p_sess, remote_fd, + new_file_fd, 1, 0); + } ++ ++ /* Need to check close operation here because some errors ++ * like EIO, EDQUOT, ENOSPC can be detected only on close ++ * when using NFS ++ */ ++ close_errno = vsf_sysutil_close_errno(new_file_fd); ++ closed = 1; ++ if (close_errno != 0) ++ { ++ trans_ret.retval = -1; ++ } ++ + if (vsf_ftpdataio_dispose_transfer_fd(p_sess) != 1 && trans_ret.retval == 0) + { + trans_ret.retval = -2; +@@ -1122,7 +1138,16 @@ handle_upload_common(struct vsf_session* p_sess, int is_append, int is_unique) + } + if (trans_ret.retval == -1) + { +- vsf_cmdio_write(p_sess, FTP_BADSENDFILE, "Failure writing to local file."); ++ /* Disk quota exceeded */ ++ if (close_errno == EDQUOT) ++ { ++ vsf_cmdio_write(p_sess, FTP_DISKQUOTA, "Disk quota exceeded."); ++ } ++ /* any other local error */ ++ else ++ { ++ vsf_cmdio_write(p_sess, FTP_BADSENDFILE, "Failure writing to local file."); ++ } + } + else if (trans_ret.retval == -2) + { +@@ -1144,7 +1169,10 @@ port_pasv_cleanup_out: + { + str_unlink(p_filename); + } +- vsf_sysutil_close(new_file_fd); ++ if (!closed) ++ { ++ vsf_sysutil_close(new_file_fd); ++ } + } + + static void +diff --git a/sysutil.c b/sysutil.c +index 01a726d..2c3659b 100644 +--- a/sysutil.c ++++ b/sysutil.c +@@ -1271,6 +1271,27 @@ vsf_sysutil_close(int fd) + } + + int ++vsf_sysutil_close_errno(int fd) ++{ ++ while (1) ++ { ++ int retval = close(fd); ++ if (retval != 0) ++ { ++ if (errno == EINTR) ++ { ++ vsf_sysutil_check_pending_actions(kVSFSysUtilUnknown, 0, 0); ++ continue; ++ } ++ else { ++ return errno; ++ } ++ } ++ return 0; ++ } ++} ++ ++int + vsf_sysutil_close_failok(int fd) + { + return close(fd); +diff --git a/sysutil.h b/sysutil.h +index 92fb7a9..c9ca9e4 100644 +--- a/sysutil.h ++++ b/sysutil.h +@@ -92,6 +92,7 @@ int vsf_sysutil_create_append_file(const char* p_filename); + int vsf_sysutil_create_or_open_file(const char* p_filename, unsigned int mode); + void vsf_sysutil_dupfd2(int old_fd, int new_fd); + void vsf_sysutil_close(int fd); ++int vsf_sysutil_close_errno(int fd); + int vsf_sysutil_close_failok(int fd); + int vsf_sysutil_unlink(const char* p_dead); + int vsf_sysutil_write_access(const char* p_filename); diff --git a/SOURCES/vsftpd-2.2.2-syslog.patch b/SOURCES/vsftpd-2.2.2-syslog.patch new file mode 100644 index 0000000..47c592e --- /dev/null +++ b/SOURCES/vsftpd-2.2.2-syslog.patch @@ -0,0 +1,13 @@ +diff --git a/logging.c b/logging.c +index 99671b4..c4461f7 100644 +--- a/logging.c ++++ b/logging.c +@@ -32,7 +32,7 @@ vsf_log_init(struct vsf_session* p_sess) + { + if (tunable_syslog_enable || tunable_tcp_wrappers) + { +- vsf_sysutil_openlog(1); ++ vsf_sysutil_openlog(0); + } + if (!tunable_xferlog_enable && !tunable_dual_log_enable) + { diff --git a/SOURCES/vsftpd-2.2.2-tlsv1_2.patch b/SOURCES/vsftpd-2.2.2-tlsv1_2.patch new file mode 100644 index 0000000..349b403 --- /dev/null +++ b/SOURCES/vsftpd-2.2.2-tlsv1_2.patch @@ -0,0 +1,116 @@ +diff --git a/parseconf.c b/parseconf.c +index a2c715b..33a1349 100644 +--- a/parseconf.c ++++ b/parseconf.c +@@ -85,6 +85,8 @@ parseconf_bool_array[] = + { "ssl_sslv2", &tunable_sslv2 }, + { "ssl_sslv3", &tunable_sslv3 }, + { "ssl_tlsv1", &tunable_tlsv1 }, ++ { "ssl_tlsv1_1", &tunable_tlsv1_1 }, ++ { "ssl_tlsv1_2", &tunable_tlsv1_2 }, + { "tilde_user_enable", &tunable_tilde_user_enable }, + { "force_anon_logins_ssl", &tunable_force_anon_logins_ssl }, + { "force_anon_data_ssl", &tunable_force_anon_data_ssl }, +diff --git a/ssl.c b/ssl.c +index da23f87..94c2b6b 100644 +--- a/ssl.c ++++ b/ssl.c +@@ -135,6 +135,14 @@ ssl_init(struct vsf_session* p_sess) + { + options |= SSL_OP_NO_TLSv1; + } ++ if (!tunable_tlsv1_1) ++ { ++ options |= SSL_OP_NO_TLSv1_1; ++ } ++ if (!tunable_tlsv1_2) ++ { ++ options |= SSL_OP_NO_TLSv1_2; ++ } + SSL_CTX_set_options(p_ctx, options); + if (tunable_rsa_cert_file) + { +diff --git a/tunables.c b/tunables.c +index 742284e..08d5490 100644 +--- a/tunables.c ++++ b/tunables.c +@@ -66,6 +66,8 @@ int tunable_force_local_data_ssl; + int tunable_sslv2; + int tunable_sslv3; + int tunable_tlsv1; ++int tunable_tlsv1_1; ++int tunable_tlsv1_2; + int tunable_tilde_user_enable; + int tunable_force_anon_logins_ssl; + int tunable_force_anon_data_ssl; +@@ -209,7 +211,9 @@ tunables_load_defaults() + tunable_force_local_data_ssl = 1; + tunable_sslv2 = 0; + tunable_sslv3 = 0; +- tunable_tlsv1 = 1; ++ tunable_tlsv1 = 0; ++ tunable_tlsv1_1 = 0; ++ tunable_tlsv1_2 = 1; + tunable_tilde_user_enable = 0; + tunable_force_anon_logins_ssl = 0; + tunable_force_anon_data_ssl = 0; +diff --git a/tunables.h b/tunables.h +index 3e2d40c..a466427 100644 +--- a/tunables.h ++++ b/tunables.h +@@ -67,6 +67,8 @@ extern int tunable_force_local_data_ssl; /* Require local data uses SSL */ + extern int tunable_sslv2; /* Allow SSLv2 */ + extern int tunable_sslv3; /* Allow SSLv3 */ + extern int tunable_tlsv1; /* Allow TLSv1 */ ++extern int tunable_tlsv1_1; /* Allow TLSv1.1 */ ++extern int tunable_tlsv1_2; /* Allow TLSv1.2 */ + extern int tunable_tilde_user_enable; /* Support e.g. ~chris */ + extern int tunable_force_anon_logins_ssl; /* Require anon logins use SSL */ + extern int tunable_force_anon_data_ssl; /* Require anon data uses SSL */ +diff --git a/vsftpd.conf.5 b/vsftpd.conf.5 +index cf1ae34..6f36b1b 100644 +--- a/vsftpd.conf.5 ++++ b/vsftpd.conf.5 +@@ -506,7 +506,7 @@ Default: YES + Only applies if + .BR ssl_enable + is activated. If enabled, this option will permit SSL v2 protocol connections. +-TLS v1 connections are preferred. ++TLS v1.2 connections are preferred. + + Default: NO + .TP +@@ -514,7 +514,7 @@ Default: NO + Only applies if + .BR ssl_enable + is activated. If enabled, this option will permit SSL v3 protocol connections. +-TLS v1 connections are preferred. ++TLS v1.2 connections are preferred. + + Default: NO + .TP +@@ -522,7 +522,23 @@ Default: NO + Only applies if + .BR ssl_enable + is activated. If enabled, this option will permit TLS v1 protocol connections. +-TLS v1 connections are preferred. ++TLS v1.2 connections are preferred. ++ ++Default: NO ++.TP ++.B ssl_tlsv1_1 ++Only applies if ++.BR ssl_enable ++is activated. If enabled, this option will permit TLS v1.1 protocol connections. ++TLS v1.2 connections are preferred. ++ ++Default: NO ++.TP ++.B ssl_tlsv1_2 ++Only applies if ++.BR ssl_enable ++is activated. If enabled, this option will permit TLS v1.2 protocol connections. ++TLS v1.2 connections are preferred. + + Default: YES + .TP diff --git a/SOURCES/vsftpd-2.3.4-sqb.patch b/SOURCES/vsftpd-2.3.4-sqb.patch index 5bf8fce..a788c77 100644 --- a/SOURCES/vsftpd-2.3.4-sqb.patch +++ b/SOURCES/vsftpd-2.3.4-sqb.patch @@ -1,7 +1,7 @@ -diff -up vsftpd-2.3.4/ls.c.sqb vsftpd-2.3.4/ls.c ---- vsftpd-2.3.4/ls.c.sqb 2011-09-13 10:37:05.222089078 +0200 -+++ vsftpd-2.3.4/ls.c 2011-09-13 10:59:19.550508941 +0200 -@@ -245,7 +245,7 @@ vsf_filename_passes_filter(const struct +diff -up vsftpd-3.0.2/ls.c.sqb vsftpd-3.0.2/ls.c +--- vsftpd-3.0.2/ls.c.sqb 2014-07-04 13:41:16.421185690 +0200 ++++ vsftpd-3.0.2/ls.c 2014-07-04 13:52:35.920369390 +0200 +@@ -246,7 +246,7 @@ vsf_filename_passes_filter(const struct int ret = 0; char last_token = 0; int must_match_at_current_pos = 1; @@ -10,7 +10,7 @@ diff -up vsftpd-2.3.4/ls.c.sqb vsftpd-2.3.4/ls.c str_copy(&filter_remain_str, p_filter_str); -@@ -275,7 +275,7 @@ vsf_filename_passes_filter(const struct +@@ -276,7 +276,7 @@ vsf_filename_passes_filter(const struct static struct mystr s_match_needed_str; /* Locate next special token */ struct str_locate_result locate_result = @@ -19,7 +19,7 @@ diff -up vsftpd-2.3.4/ls.c.sqb vsftpd-2.3.4/ls.c (*iters)++; /* Isolate text leading up to token (if any) - needs to be matched */ if (locate_result.found) -@@ -293,94 +293,170 @@ vsf_filename_passes_filter(const struct +@@ -294,94 +294,172 @@ vsf_filename_passes_filter(const struct str_empty(&filter_remain_str); last_token = 0; } @@ -31,28 +31,13 @@ diff -up vsftpd-2.3.4/ls.c.sqb vsftpd-2.3.4/ls.c - unsigned int indexx; - locate_result = str_locate_str(&name_remain_str, &s_match_needed_str); - if (!locate_result.found) -- { -- /* Fail */ -- goto out; -- } -- indexx = locate_result.index; -- if (must_match_at_current_pos && indexx > 0) -- { -- goto out; -- } -- if (!must_match_at_current_pos && last_token == 0) -- { -- struct mystr last_str = INIT_MYSTR; -- str_mid_to_end(&name_remain_str, &last_str, -- str_getlen(&name_remain_str) - str_getlen(&s_match_needed_str)); -- locate_result = str_locate_str(&last_str, &s_match_needed_str); -- str_free(&last_str); - -- if (locate_result.found) ++ + matched = 0; + do { + if (!str_isempty(&s_match_needed_str)) -+ { + { +- /* Fail */ +- goto out; + if (!matched) + { + matched = 1; @@ -69,11 +54,9 @@ diff -up vsftpd-2.3.4/ls.c.sqb vsftpd-2.3.4/ls.c + } + indexx = locate_result.index; + if (must_match_at_current_pos && indexx > 0) - { -- ret = 1; ++ { + goto out; - } -- goto out; ++ } + if (!must_match_at_current_pos && last_token == 0) + { + struct mystr last_str = INIT_MYSTR; @@ -93,14 +76,8 @@ diff -up vsftpd-2.3.4/ls.c.sqb vsftpd-2.3.4/ls.c + indexx + str_getlen(&s_match_needed_str)); + str_copy(&name_remain_str, &temp_str); } -- /* Chop matched string out of remainder */ -- str_mid_to_end(&name_remain_str, &temp_str, -- indexx + str_getlen(&s_match_needed_str)); -- str_copy(&name_remain_str, &temp_str); -- } -- if (last_token == '?') -- { -- if (str_isempty(&name_remain_str)) +- indexx = locate_result.index; +- if (must_match_at_current_pos && indexx > 0) + if (last_token == '?') { - goto out; @@ -112,43 +89,30 @@ diff -up vsftpd-2.3.4/ls.c.sqb vsftpd-2.3.4/ls.c + str_copy(&name_remain_str, &temp_str); + must_match_at_current_pos = 1; } -- str_right(&name_remain_str, &temp_str, str_getlen(&name_remain_str) - 1); -- str_copy(&name_remain_str, &temp_str); -- must_match_at_current_pos = 1; -- } -- else if (last_token == '{') -- { -- struct str_locate_result end_brace = -- str_locate_char(&filter_remain_str, '}'); -- must_match_at_current_pos = 1; -- if (end_brace.found) +- if (!must_match_at_current_pos && last_token == 0) + else if (last_token == '{') { -- str_split_char(&filter_remain_str, &temp_str, '}'); -- str_copy(&brace_list_str, &filter_remain_str); -- str_copy(&filter_remain_str, &temp_str); -- str_split_char(&brace_list_str, &temp_str, ','); -- while (!str_isempty(&brace_list_str)) -- { -- str_copy(&new_filter_str, &brace_list_str); -- str_append_str(&new_filter_str, &filter_remain_str); -- if (vsf_filename_passes_filter(&name_remain_str, &new_filter_str, -- iters)) +- struct mystr last_str = INIT_MYSTR; +- str_mid_to_end(&name_remain_str, &last_str, +- str_getlen(&name_remain_str) - str_getlen(&s_match_needed_str)); +- locate_result = str_locate_str(&last_str, &s_match_needed_str); +- str_free(&last_str); + struct str_locate_result end_brace = + str_locate_char(&filter_remain_str, '}'); + must_match_at_current_pos = 1; + if (end_brace.found) + { ++ int entire = (*iters == 1 && last_token == '{'); + +- if (locate_result.found) + str_split_char(&filter_remain_str, &temp_str, '}'); + str_copy(&brace_list_str, &filter_remain_str); + str_copy(&filter_remain_str, &temp_str); + str_split_char(&brace_list_str, &temp_str, ','); + while (!str_isempty(&brace_list_str)) - { -- ret = 1; -- goto out; ++ { + str_empty(&new_filter_str); -+ if (!matched) ++ if (!matched && !entire) + { + str_append_char(&new_filter_str, '*'); + } @@ -162,14 +126,13 @@ diff -up vsftpd-2.3.4/ls.c.sqb vsftpd-2.3.4/ls.c + } + str_copy(&brace_list_str, &temp_str); + str_split_char(&brace_list_str, &temp_str, ','); - } -- str_copy(&brace_list_str, &temp_str); -- str_split_char(&brace_list_str, &temp_str, ','); ++ } + goto out; + } + else if (str_isempty(&name_remain_str) || + str_get_char_at(&name_remain_str, 0) != '{') -+ { + { +- ret = 1; + goto out; + } + else @@ -179,12 +142,40 @@ diff -up vsftpd-2.3.4/ls.c.sqb vsftpd-2.3.4/ls.c + str_copy(&name_remain_str, &temp_str); } - goto out; +- } +- /* Chop matched string out of remainder */ +- str_mid_to_end(&name_remain_str, &temp_str, +- indexx + str_getlen(&s_match_needed_str)); +- str_copy(&name_remain_str, &temp_str); +- } +- if (last_token == '?') +- { +- if (str_isempty(&name_remain_str)) +- { +- goto out; } -- else if (str_isempty(&name_remain_str) || -- str_get_char_at(&name_remain_str, 0) != '{') +- str_right(&name_remain_str, &temp_str, str_getlen(&name_remain_str) - 1); +- str_copy(&name_remain_str, &temp_str); +- must_match_at_current_pos = 1; +- } +- else if (last_token == '{') +- { +- struct str_locate_result end_brace = +- str_locate_char(&filter_remain_str, '}'); +- must_match_at_current_pos = 1; +- if (end_brace.found) + else if (last_token == '[') { -- goto out; +- str_split_char(&filter_remain_str, &temp_str, '}'); +- str_copy(&brace_list_str, &filter_remain_str); +- str_copy(&filter_remain_str, &temp_str); +- str_split_char(&brace_list_str, &temp_str, ','); +- while (!str_isempty(&brace_list_str)) +- { +- str_copy(&new_filter_str, &brace_list_str); +- str_append_str(&new_filter_str, &filter_remain_str); +- if (vsf_filename_passes_filter(&name_remain_str, &new_filter_str, +- iters)) + struct str_locate_result end_sqb = + str_locate_char(&filter_remain_str, ']'); + must_match_at_current_pos = 1; @@ -199,7 +190,9 @@ diff -up vsftpd-2.3.4/ls.c.sqb vsftpd-2.3.4/ls.c + str_copy(&filter_remain_str, &temp_str); + p_brace = str_getbuf(&brace_list_str); + for (cur_pos = 0; cur_pos < str_getlen(&brace_list_str);) -+ { + { +- ret = 1; +- goto out; + stch = p_brace[cur_pos]; + // char vers. range + if (cur_pos + 2 < str_getlen(&brace_list_str) && @@ -230,7 +223,9 @@ diff -up vsftpd-2.3.4/ls.c.sqb vsftpd-2.3.4/ls.c + goto out; + } + } -+ } + } +- str_copy(&brace_list_str, &temp_str); +- str_split_char(&brace_list_str, &temp_str, ','); + goto out; + } + else if (str_isempty(&name_remain_str) || @@ -243,7 +238,13 @@ diff -up vsftpd-2.3.4/ls.c.sqb vsftpd-2.3.4/ls.c + str_right(&name_remain_str, &temp_str, + str_getlen(&name_remain_str) - 1); + str_copy(&name_remain_str, &temp_str); -+ } + } +- goto out; +- } +- else if (str_isempty(&name_remain_str) || +- str_get_char_at(&name_remain_str, 0) != '{') +- { +- goto out; } else { diff --git a/SOURCES/vsftpd-3.0.2-del-upl.patch b/SOURCES/vsftpd-3.0.2-del-upl.patch new file mode 100644 index 0000000..15f511e --- /dev/null +++ b/SOURCES/vsftpd-3.0.2-del-upl.patch @@ -0,0 +1,118 @@ +diff --git a/ftpcodes.h b/ftpcodes.h +index 93290c0..995788a 100644 +--- a/ftpcodes.h ++++ b/ftpcodes.h +@@ -15,7 +15,8 @@ + #define FTP_PBSZOK 200 + #define FTP_PROTOK 200 + #define FTP_OPTSOK 200 +-#define FTP_ALLOOK 202 ++#define FTP_ALLOOK 200 ++#define FTP_ALLOIGN 202 + #define FTP_FEAT 211 + #define FTP_STATOK 211 + #define FTP_SIZEOK 213 +diff --git a/ftpdataio.c b/ftpdataio.c +index ffb2e23..08b0628 100644 +--- a/ftpdataio.c ++++ b/ftpdataio.c +@@ -244,6 +244,10 @@ init_data_sock_params(struct vsf_session* p_sess, int sock_fd) + /* Start the timeout monitor */ + vsf_sysutil_install_io_handler(handle_io, p_sess); + start_data_alarm(p_sess); ++ if(tunable_delete_failed_uploads) ++ { ++ vsf_sysutil_rcvtimeo(sock_fd); ++ } + } + + static void +@@ -617,6 +621,10 @@ do_file_recv(struct vsf_session* p_sess, int file_fd, int is_ascii) + else if (retval == 0 && !prev_cr) + { + /* Transfer done, nifty */ ++ if (tunable_delete_failed_uploads && ++ !is_ascii && p_sess->upload_size > 0 && ++ p_sess->upload_size != ret_struct.transferred) ++ ret_struct.retval = -2; + return ret_struct; + } + num_to_write = (unsigned int) retval; +diff --git a/main.c b/main.c +index f1e2f69..f039081 100644 +--- a/main.c ++++ b/main.c +@@ -44,7 +44,7 @@ main(int argc, const char* argv[]) + /* Login */ + 1, 0, INIT_MYSTR, INIT_MYSTR, + /* Protocol state */ +- 0, 1, INIT_MYSTR, 0, 0, ++ 0, 0, 1, INIT_MYSTR, 0, 0, + /* HTTP hacks */ + 0, INIT_MYSTR, + /* Session state */ +diff --git a/postlogin.c b/postlogin.c +index 8a83164..4ca7f2c 100644 +--- a/postlogin.c ++++ b/postlogin.c +@@ -356,7 +356,14 @@ process_post_login(struct vsf_session* p_sess) + } + else if (str_equal_text(&p_sess->ftp_cmd_str, "ALLO")) + { +- vsf_cmdio_write(p_sess, FTP_ALLOOK, "ALLO command ignored."); ++ if (tunable_delete_failed_uploads && !p_sess->is_ascii) ++ { ++ p_sess->upload_size = (filesize_t)vsf_sysutil_atoi(str_getbuf(&p_sess->ftp_cmd_str)+5); ++ vsf_cmdio_write(p_sess, FTP_ALLOOK, "The filesize has been allocated."); ++ } ++ else { ++ vsf_cmdio_write(p_sess, FTP_ALLOIGN, "ALLO command ignored."); ++ } + } + else if (str_equal_text(&p_sess->ftp_cmd_str, "REIN")) + { +diff --git a/session.h b/session.h +index 8123ffc..b60e098 100644 +--- a/session.h ++++ b/session.h +@@ -41,6 +41,7 @@ struct vsf_session + struct mystr anon_pass_str; + + /* Details of the FTP protocol state */ ++ filesize_t upload_size; + filesize_t restart_pos; + int is_ascii; + struct mystr rnfr_filename_str; +diff --git a/sysutil.c b/sysutil.c +index af41e32..927174f 100644 +--- a/sysutil.c ++++ b/sysutil.c +@@ -681,6 +681,16 @@ vsf_sysutil_activate_keepalive(int fd) + } + + void ++vsf_sysutil_rcvtimeo(int fd) ++{ ++ struct timeval tv; ++ ++ tv.tv_sec = tunable_data_connection_timeout; ++ tv.tv_usec = 0; ++ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval)); ++} ++ ++void + vsf_sysutil_activate_reuseaddr(int fd) + { + int reuseaddr = 1; +diff --git a/sysutil.h b/sysutil.h +index 959fdf4..bb55063 100644 +--- a/sysutil.h ++++ b/sysutil.h +@@ -265,6 +265,7 @@ void vsf_sysutil_dns_resolve(struct vsf_sysutil_sockaddr** p_sockptr, + const char* p_name); + /* Option setting on sockets */ + void vsf_sysutil_activate_keepalive(int fd); ++void vsf_sysutil_rcvtimeo(int fd); + void vsf_sysutil_set_iptos_throughput(int fd); + void vsf_sysutil_activate_reuseaddr(int fd); + void vsf_sysutil_set_nodelay(int fd); diff --git a/SOURCES/vsftpd-3.0.2-docupd.patch b/SOURCES/vsftpd-3.0.2-docupd.patch new file mode 100644 index 0000000..6c03703 --- /dev/null +++ b/SOURCES/vsftpd-3.0.2-docupd.patch @@ -0,0 +1,49 @@ +diff --git a/vsftpd.conf.5 b/vsftpd.conf.5 +index 10e9f45..cf1ae34 100644 +--- a/vsftpd.conf.5 ++++ b/vsftpd.conf.5 +@@ -653,6 +653,21 @@ change it with the setting + .BR xferlog_file . + + Default: NO ++.TP ++.B isolate_network ++If enabled, use CLONE_NEWNET to isolate the untrusted processes so that ++they can't do arbitrary connect() and instead have to ask the privileged ++process for sockets ( ++.BR port_promiscuous ++have to be disabled). ++ ++Default: YES ++.TP ++.B isolate ++If enabled, use CLONE_NEWPID and CLONE_NEWIPC to isolate processes to their ++ipc and pid namespaces. So separated processes can not interact with each other. ++ ++Default: YES + + .SH NUMERIC OPTIONS + Below is a list of numeric options. A numeric option must be set to a non +@@ -750,8 +765,9 @@ Default: 077 + .B max_clients + If vsftpd is in standalone mode, this is the maximum number of clients which + may be connected. Any additional clients connecting will get an error message. ++The value 0 switches off the limit. + +-Default: 0 (unlimited) ++Default: 2000 + .TP + .B max_login_fails + After this many login failures, the session is killed. +@@ -761,9 +777,9 @@ Default: 3 + .B max_per_ip + If vsftpd is in standalone mode, this is the maximum number of clients which + may be connected from the same source internet address. A client will get an +-error message if they go over this limit. ++error message if they go over this limit. The value 0 switches off the limit. + +-Default: 0 (unlimited) ++Default: 50 + .TP + .B pasv_max_port + The maximum port to allocate for PASV style data connections. Can be used to diff --git a/SOURCES/vsftpd-3.0.2-reverse-lookup.patch b/SOURCES/vsftpd-3.0.2-reverse-lookup.patch new file mode 100644 index 0000000..8f5e5a6 --- /dev/null +++ b/SOURCES/vsftpd-3.0.2-reverse-lookup.patch @@ -0,0 +1,85 @@ +diff -up vsftpd-3.0.2/parseconf.c.lookup vsftpd-3.0.2/parseconf.c +--- vsftpd-3.0.2/parseconf.c.lookup 2014-04-17 10:01:50.862951491 +0200 ++++ vsftpd-3.0.2/parseconf.c 2014-04-17 10:02:42.343955443 +0200 +@@ -91,6 +91,7 @@ parseconf_bool_array[] = + { "mdtm_write", &tunable_mdtm_write }, + { "lock_upload_files", &tunable_lock_upload_files }, + { "pasv_addr_resolve", &tunable_pasv_addr_resolve }, ++ { "reverse_lookup_enable", &tunable_reverse_lookup_enable }, + { "userlist_log", &tunable_userlist_log }, + { "debug_ssl", &tunable_debug_ssl }, + { "require_cert", &tunable_require_cert }, +diff -up vsftpd-3.0.2/sysdeputil.c.lookup vsftpd-3.0.2/sysdeputil.c +--- vsftpd-3.0.2/sysdeputil.c.lookup 2014-04-17 09:57:02.111933144 +0200 ++++ vsftpd-3.0.2/sysdeputil.c 2014-04-17 10:01:31.069950498 +0200 +@@ -354,12 +354,16 @@ vsf_sysdep_check_auth(struct mystr* p_us + return 0; + } + #ifdef PAM_RHOST +- sin.sin_addr.s_addr = inet_addr(str_getbuf(p_remote_host)); +- host = gethostbyaddr((char*)&sin.sin_addr.s_addr,sizeof(struct in_addr),AF_INET); +- if (host != (struct hostent*)0) +- retval = pam_set_item(s_pamh, PAM_RHOST, host->h_name); +- else ++ if (tunable_reverse_lookup_enable) { ++ sin.sin_addr.s_addr = inet_addr(str_getbuf(p_remote_host)); ++ host = gethostbyaddr((char*)&sin.sin_addr.s_addr,sizeof(struct in_addr),AF_INET); ++ if (host != (struct hostent*)0) ++ retval = pam_set_item(s_pamh, PAM_RHOST, host->h_name); ++ else ++ retval = pam_set_item(s_pamh, PAM_RHOST, str_getbuf(p_remote_host)); ++ } else { + retval = pam_set_item(s_pamh, PAM_RHOST, str_getbuf(p_remote_host)); ++ } + if (retval != PAM_SUCCESS) + { + (void) pam_end(s_pamh, retval); +diff -up vsftpd-3.0.2/tunables.c.lookup vsftpd-3.0.2/tunables.c +--- vsftpd-3.0.2/tunables.c.lookup 2014-04-17 10:03:22.766958324 +0200 ++++ vsftpd-3.0.2/tunables.c 2014-04-17 10:04:52.004964675 +0200 +@@ -72,6 +72,7 @@ int tunable_force_anon_data_ssl; + int tunable_mdtm_write; + int tunable_lock_upload_files; + int tunable_pasv_addr_resolve; ++int tunable_reverse_lookup_enable; + int tunable_userlist_log; + int tunable_debug_ssl; + int tunable_require_cert; +@@ -213,6 +214,7 @@ tunables_load_defaults() + tunable_mdtm_write = 1; + tunable_lock_upload_files = 1; + tunable_pasv_addr_resolve = 0; ++ tunable_reverse_lookup_enable = 1; + tunable_userlist_log = 0; + tunable_debug_ssl = 0; + tunable_require_cert = 0; +diff -up vsftpd-3.0.2/tunables.h.lookup vsftpd-3.0.2/tunables.h +--- vsftpd-3.0.2/tunables.h.lookup 2014-04-17 10:03:27.405958676 +0200 ++++ vsftpd-3.0.2/tunables.h 2014-04-17 10:04:22.763963824 +0200 +@@ -73,6 +73,7 @@ extern int tunable_force_anon_data_ssl; + extern int tunable_mdtm_write; /* Allow MDTM to set timestamps */ + extern int tunable_lock_upload_files; /* Lock uploading files */ + extern int tunable_pasv_addr_resolve; /* DNS resolve pasv_addr */ ++extern int tunable_reverse_lookup_enable; /* Get hostname before pam auth */ + extern int tunable_userlist_log; /* Log every failed login attempt */ + extern int tunable_debug_ssl; /* Verbose SSL logging */ + extern int tunable_require_cert; /* SSL client cert required */ +diff -up vsftpd-3.0.2/vsftpd.conf.5.lookup vsftpd-3.0.2/vsftpd.conf.5 +--- vsftpd-3.0.2/vsftpd.conf.5.lookup 2014-04-17 10:05:30.956969003 +0200 ++++ vsftpd-3.0.2/vsftpd.conf.5 2014-04-17 10:06:36.586971828 +0200 +@@ -425,6 +425,15 @@ http://scarybeastsecurity.blogspot.com/2 + + Default: YES + .TP ++.B reverse_lookup_enable ++Set to YES if you want vsftpd to transform the ip address into the hostname, ++before pam authentication. This is useful if you use pam_access including the ++hostname. If you want vsftpd to run on the environment where the reverse lookup ++for some hostname is available and the name server doesn't respond for a while, ++you should set this to NO to avoid a performance issue. ++ ++Default: YES ++.TP + .B run_as_launching_user + Set to YES if you want vsftpd to run as the user which launched vsftpd. This is + useful where root access is not available. MASSIVE WARNING! Do NOT enable this diff --git a/SOURCES/vsftpd-3.0.2-uint-uidgid.patch b/SOURCES/vsftpd-3.0.2-uint-uidgid.patch new file mode 100644 index 0000000..452bb57 --- /dev/null +++ b/SOURCES/vsftpd-3.0.2-uint-uidgid.patch @@ -0,0 +1,234 @@ +diff --git a/ls.c b/ls.c +index 0898576..e9829d9 100644 +--- a/ls.c ++++ b/ls.c +@@ -502,7 +502,7 @@ build_dir_line(struct mystr* p_str, const struct mystr* p_filename_str, + } + else + { +- int uid = vsf_sysutil_statbuf_get_uid(p_stat); ++ unsigned int uid = vsf_sysutil_statbuf_get_uid(p_stat); + struct vsf_sysutil_user* p_user = 0; + if (tunable_text_userdb_names) + { +@@ -527,7 +527,7 @@ build_dir_line(struct mystr* p_str, const struct mystr* p_filename_str, + } + else + { +- int gid = vsf_sysutil_statbuf_get_gid(p_stat); ++ unsigned int gid = vsf_sysutil_statbuf_get_gid(p_stat); + struct vsf_sysutil_group* p_group = 0; + if (tunable_text_userdb_names) + { +diff --git a/privops.c b/privops.c +index 21d7267..f27c5c4 100644 +--- a/privops.c ++++ b/privops.c +@@ -236,8 +236,7 @@ vsf_privop_do_file_chown(struct vsf_session* p_sess, int fd) + /* Drop it like a hot potato unless it's a regular file owned by + * the the anonymous ftp user + */ +- if (p_sess->anon_upload_chown_uid == -1 || +- !vsf_sysutil_statbuf_is_regfile(s_p_statbuf) || ++ if (!vsf_sysutil_statbuf_is_regfile(s_p_statbuf) || + (vsf_sysutil_statbuf_get_uid(s_p_statbuf) != p_sess->anon_ftp_uid && + vsf_sysutil_statbuf_get_uid(s_p_statbuf) != p_sess->guest_user_uid)) + { +diff --git a/session.h b/session.h +index b60e098..4eccf46 100644 +--- a/session.h ++++ b/session.h +@@ -56,9 +56,9 @@ struct vsf_session + struct mystr_list* p_visited_dir_list; + + /* Details of userids which are interesting to us */ +- int anon_ftp_uid; +- int guest_user_uid; +- int anon_upload_chown_uid; ++ unsigned int anon_ftp_uid; ++ unsigned int guest_user_uid; ++ unsigned int anon_upload_chown_uid; + + /* Things we need to cache before we chroot() */ + struct mystr banned_email_str; +diff --git a/sysutil.c b/sysutil.c +index 24c4a81..954e901 100644 +--- a/sysutil.c ++++ b/sysutil.c +@@ -1485,14 +1485,14 @@ vsf_sysutil_statbuf_get_size(const struct vsf_sysutil_statbuf* p_statbuf) + return p_stat->st_size; + } + +-int ++unsigned int + vsf_sysutil_statbuf_get_uid(const struct vsf_sysutil_statbuf* p_statbuf) + { + const struct stat* p_stat = (const struct stat*) p_statbuf; + return p_stat->st_uid; + } + +-int ++unsigned int + vsf_sysutil_statbuf_get_gid(const struct vsf_sysutil_statbuf* p_statbuf) + { + const struct stat* p_stat = (const struct stat*) p_statbuf; +@@ -1533,7 +1533,7 @@ vsf_sysutil_statbuf_get_sortkey_mtime( + } + + void +-vsf_sysutil_fchown(const int fd, const int uid, const int gid) ++vsf_sysutil_fchown(const int fd, const unsigned int uid, const unsigned int gid) + { + if (fchown(fd, uid, gid) != 0) + { +@@ -2351,13 +2351,9 @@ vsf_sysutil_dns_resolve(struct vsf_sysutil_sockaddr** p_sockptr, + } + + struct vsf_sysutil_user* +-vsf_sysutil_getpwuid(const int uid) ++vsf_sysutil_getpwuid(const unsigned int uid) + { +- if (uid < 0) +- { +- bug("negative uid in vsf_sysutil_getpwuid"); +- } +- return (struct vsf_sysutil_user*) getpwuid((unsigned int) uid); ++ return (struct vsf_sysutil_user*) getpwuid(uid); + } + + struct vsf_sysutil_user* +@@ -2380,14 +2376,14 @@ vsf_sysutil_user_get_homedir(const struct vsf_sysutil_user* p_user) + return p_passwd->pw_dir; + } + +-int ++unsigned int + vsf_sysutil_user_getuid(const struct vsf_sysutil_user* p_user) + { + const struct passwd* p_passwd = (const struct passwd*) p_user; + return p_passwd->pw_uid; + } + +-int ++unsigned int + vsf_sysutil_user_getgid(const struct vsf_sysutil_user* p_user) + { + const struct passwd* p_passwd = (const struct passwd*) p_user; +@@ -2395,13 +2391,9 @@ vsf_sysutil_user_getgid(const struct vsf_sysutil_user* p_user) + } + + struct vsf_sysutil_group* +-vsf_sysutil_getgrgid(const int gid) ++vsf_sysutil_getgrgid(const unsigned int gid) + { +- if (gid < 0) +- { +- die("negative gid in vsf_sysutil_getgrgid"); +- } +- return (struct vsf_sysutil_group*) getgrgid((unsigned int) gid); ++ return (struct vsf_sysutil_group*) getgrgid(gid); + } + + const char* +@@ -2476,25 +2468,17 @@ vsf_sysutil_setgid_numeric(int gid) + } + } + +-int ++unsigned int + vsf_sysutil_geteuid(void) + { +- int retval = geteuid(); +- if (retval < 0) +- { +- die("geteuid"); +- } ++ unsigned int retval = geteuid(); + return retval; + } + +-int ++unsigned int + vsf_sysutil_getegid(void) + { +- int retval = getegid(); +- if (retval < 0) +- { +- die("getegid"); +- } ++ unsigned int retval = getegid(); + return retval; + } + +@@ -2885,7 +2869,7 @@ vsf_sysutil_ftruncate(int fd) + } + } + +-int ++unsigned int + vsf_sysutil_getuid(void) + { + return getuid(); +diff --git a/sysutil.h b/sysutil.h +index 399c921..b745d4a 100644 +--- a/sysutil.h ++++ b/sysutil.h +@@ -130,15 +130,15 @@ const char* vsf_sysutil_statbuf_get_numeric_date( + const struct vsf_sysutil_statbuf* p_stat, int use_localtime); + unsigned int vsf_sysutil_statbuf_get_links( + const struct vsf_sysutil_statbuf* p_stat); +-int vsf_sysutil_statbuf_get_uid(const struct vsf_sysutil_statbuf* p_stat); +-int vsf_sysutil_statbuf_get_gid(const struct vsf_sysutil_statbuf* p_stat); ++unsigned int vsf_sysutil_statbuf_get_uid(const struct vsf_sysutil_statbuf* p_stat); ++unsigned int vsf_sysutil_statbuf_get_gid(const struct vsf_sysutil_statbuf* p_stat); + int vsf_sysutil_statbuf_is_readable_other( + const struct vsf_sysutil_statbuf* p_stat); + const char* vsf_sysutil_statbuf_get_sortkey_mtime( + const struct vsf_sysutil_statbuf* p_stat); + + int vsf_sysutil_chmod(const char* p_filename, unsigned int mode); +-void vsf_sysutil_fchown(const int fd, const int uid, const int gid); ++void vsf_sysutil_fchown(const int fd, const unsigned int uid, const unsigned int gid); + void vsf_sysutil_fchmod(const int fd, unsigned int mode); + int vsf_sysutil_readlink(const char* p_filename, char* p_dest, + unsigned int bufsiz); +@@ -292,15 +292,15 @@ int vsf_sysutil_inet_aton( + struct vsf_sysutil_user; + struct vsf_sysutil_group; + +-struct vsf_sysutil_user* vsf_sysutil_getpwuid(const int uid); ++struct vsf_sysutil_user* vsf_sysutil_getpwuid(const unsigned int uid); + struct vsf_sysutil_user* vsf_sysutil_getpwnam(const char* p_user); + const char* vsf_sysutil_user_getname(const struct vsf_sysutil_user* p_user); + const char* vsf_sysutil_user_get_homedir( + const struct vsf_sysutil_user* p_user); +-int vsf_sysutil_user_getuid(const struct vsf_sysutil_user* p_user); +-int vsf_sysutil_user_getgid(const struct vsf_sysutil_user* p_user); ++unsigned int vsf_sysutil_user_getuid(const struct vsf_sysutil_user* p_user); ++unsigned int vsf_sysutil_user_getgid(const struct vsf_sysutil_user* p_user); + +-struct vsf_sysutil_group* vsf_sysutil_getgrgid(const int gid); ++struct vsf_sysutil_group* vsf_sysutil_getgrgid(const unsigned int gid); + const char* vsf_sysutil_group_getname(const struct vsf_sysutil_group* p_group); + + /* More random things */ +@@ -318,7 +318,7 @@ void vsf_sysutil_qsort(void* p_base, unsigned int num_elem, + char* vsf_sysutil_getenv(const char* p_var); + typedef void (*exitfunc_t)(void); + void vsf_sysutil_set_exit_func(exitfunc_t exitfunc); +-int vsf_sysutil_getuid(void); ++unsigned int vsf_sysutil_getuid(void); + + /* Syslogging (bah) */ + void vsf_sysutil_openlog(int force); +@@ -331,8 +331,8 @@ void vsf_sysutil_setuid(const struct vsf_sysutil_user* p_user); + void vsf_sysutil_setgid(const struct vsf_sysutil_user* p_user); + void vsf_sysutil_setuid_numeric(int uid); + void vsf_sysutil_setgid_numeric(int gid); +-int vsf_sysutil_geteuid(void); +-int vsf_sysutil_getegid(void); ++unsigned int vsf_sysutil_geteuid(void); ++unsigned int vsf_sysutil_getegid(void); + void vsf_sysutil_seteuid(const struct vsf_sysutil_user* p_user); + void vsf_sysutil_setegid(const struct vsf_sysutil_user* p_user); + void vsf_sysutil_seteuid_numeric(int uid); diff --git a/SPECS/vsftpd.spec b/SPECS/vsftpd.spec index 38e983e..a37f1a9 100644 --- a/SPECS/vsftpd.spec +++ b/SPECS/vsftpd.spec @@ -3,7 +3,7 @@ Name: vsftpd Version: 3.0.2 -Release: 11%{?dist} +Release: 21%{?dist} Summary: Very Secure Ftp Daemon Group: System Environment/Daemons @@ -66,6 +66,15 @@ Patch28: vsftpd-3.0.2-wnohang.patch Patch29: vsftpd-3.0.2-dh.patch Patch30: vsftpd-3.0.2-ecdh.patch Patch31: vsftpd-2.0.5-fix_qm.patch +Patch32: vsftpd-3.0.2-reverse-lookup.patch +Patch33: vsftpd-3.0.2-del-upl.patch +Patch34: vsftpd-2.2.2-nfs-fail.patch +Patch35: vsftpd-2.2.2-man-pages.patch +Patch36: vsftpd-3.0.2-uint-uidgid.patch +Patch37: vsftpd-2.2.2-blank-chars-overflow.patch +Patch38: vsftpd-2.2.2-syslog.patch +Patch39: vsftpd-3.0.2-docupd.patch +Patch40: vsftpd-2.2.2-tlsv1_2.patch %description vsftpd is a Very Secure FTP daemon. It was written completely from @@ -112,6 +121,15 @@ cp %{SOURCE1} . %patch29 -p1 -b .dh %patch30 -p1 -b .ecdh %patch31 -p1 -b .fix_qm +%patch32 -p1 -b .reverse-lookup +%patch33 -p1 -b .del-upl +%patch34 -p1 -b .nfs-fail +%patch35 -p1 -b .man_pages +%patch36 -p1 -b .uint-uidgid +%patch37 -p1 -b .blank-char-overflow +%patch38 -p1 -b .syslog +%patch39 -p1 -b .docup +%patch40 -p1 -b .tls_version %build %ifarch s390x sparcv9 sparc64 @@ -182,6 +200,40 @@ rm -rf $RPM_BUILD_ROOT %{_sysconfdir}/rc.d/init.d/vsftpd %changelog +* Thu Jun 02 2016 Martin Sehnoutka - 3.0.2-21 +- Resolves: #1318947 vsftpd should permit specified TLS versions only + +* Thu Apr 07 2016 Martin Sehnoutka - 3.0.2-20 +- Resolves: #1147551 - Missing isolate_* options, incorrect default values of + max_clients, max_per_ip in man vsftpd.conf + +* Tue Apr 05 2016 Martin Sehnoutka - 3.0.2-19 +- Resolves: #1311562 - Message is not logged to syslog when syslog_enable=yes in + vsftpd.conf + +* Tue Apr 05 2016 Martin Sehnoutka - 3.0.2-18 +- Resolves: #1311600 - vsftpd segfaults in vsf_sysutil_strndup + +* Fri Apr 01 2016 Martin Sehnoutka - 3.0.2-17 +- Resolves: #1116385 - deny_file, hide_file + +* Tue Mar 29 2016 Martin Sehnoutka - 3.0.2-16 +- Resolves: #1087868 - uid and gid is not correctly shown + +* Tue Mar 29 2016 Martin Sehnoutka - 3.0.2-15 +- Resolves: #1147550 ssl_request_cert paragraph in the vsftpd.conf man page gets + rendered incorrectly + +* Tue Mar 29 2016 Martin Sehnoutka - 3.0.2-14 +- Resolves: #1317891 Handle errors when calling close() + +* Thu Mar 24 2016 Martin Sehnoutka - 3.0.2-13 +- Resolves: #1148872 - The vsftpd doesn't remove failed upload when the + delete_failed_uploads is enabled and the network cable is unplagged + +* Tue Mar 22 2016 Martin Sehnoutka - 3.0.2-12 +- Resolves: #1087834 - missing reverse_lookup_enable option + * Tue Feb 23 2016 Pavel Šimerda - 3.0.2-11 - Resolves: #1166741 - Wildcard ? does not work correctly in vsftpd-3.0.2-9.el7