mirror of
https://github.com/InfrastructureServices/vsftpd.git
synced 2025-04-19 01:24:02 +03:00
Updated to v2.0.7
This commit is contained in:
parent
2b30cb98d0
commit
19940a28a1
17
Changelog
17
Changelog
@ -975,3 +975,20 @@ to require fully valid / authentic client certs. No cert-based auth yet.
|
||||
|
||||
At this point: v2.0.6 released!
|
||||
===============================
|
||||
|
||||
- Fix finding libcap for the link on Slackware systems, thanks to Roman
|
||||
Kravchenko <roman@atech.lv>.
|
||||
- Fix build on Solaris 2.8 due to non-standard C, thanks to IIDA Yosiaki
|
||||
<y-iida@secom.co.jp>.
|
||||
- Fix man page typo, thanks Matt Selsky <selsky@columbia.edu>.
|
||||
- Bring the PASV listen() into the bind() retry loop to resolve a race under
|
||||
extreme load. Thanks to Curtis Taylor <cjt@us.ibm.com>.
|
||||
- Enhance logging for debug_ssl.
|
||||
- Shutdown the SSL data connections properly. This prevents clients such as
|
||||
recent FileZilla from complaining. Reported by various people.
|
||||
- Add option to enforce proper SSL shutdown on uploads. Left it off after much
|
||||
agonizing because clients are so broken in this area.
|
||||
- Add option to delete failed uploads.
|
||||
|
||||
At this point: v2.0.7 released!
|
||||
===============================
|
||||
|
2
README
2
README
@ -1,4 +1,4 @@
|
||||
This is vsftpd, version 2.0.6
|
||||
This is vsftpd, version 2.0.7
|
||||
Author: Chris Evans
|
||||
Contact: scarybeasts@gmail.com
|
||||
Website: http://vsftpd.beasts.org/
|
||||
|
@ -51,9 +51,10 @@ static int write_dir_list(struct vsf_session* p_sess,
|
||||
enum EVSFRWTarget target);
|
||||
static unsigned int get_chunk_size();
|
||||
|
||||
void
|
||||
int
|
||||
vsf_ftpdataio_dispose_transfer_fd(struct vsf_session* p_sess)
|
||||
{
|
||||
int dispose_ret = 1;
|
||||
int retval;
|
||||
if (p_sess->data_fd == -1)
|
||||
{
|
||||
@ -64,7 +65,7 @@ vsf_ftpdataio_dispose_transfer_fd(struct vsf_session* p_sess)
|
||||
vsf_sysutil_uninstall_io_handler();
|
||||
if (p_sess->p_data_ssl != 0)
|
||||
{
|
||||
ssl_data_close(p_sess);
|
||||
dispose_ret = ssl_data_close(p_sess);
|
||||
}
|
||||
/* This close() blocks because we set SO_LINGER */
|
||||
retval = vsf_sysutil_close_failok(p_sess->data_fd);
|
||||
@ -76,6 +77,7 @@ vsf_ftpdataio_dispose_transfer_fd(struct vsf_session* p_sess)
|
||||
}
|
||||
vsf_sysutil_clear_alarm();
|
||||
p_sess->data_fd = -1;
|
||||
return dispose_ret;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -15,8 +15,11 @@ struct vsf_session;
|
||||
* timeout goes off, or the connection is severed).
|
||||
* PARAMETERS
|
||||
* p_sess - the current FTP session object
|
||||
* RETURNS
|
||||
* 1 on success, 0 otherwise.
|
||||
*
|
||||
*/
|
||||
void vsf_ftpdataio_dispose_transfer_fd(struct vsf_session* p_sess);
|
||||
int vsf_ftpdataio_dispose_transfer_fd(struct vsf_session* p_sess);
|
||||
|
||||
/* vsf_ftpdataio_get_pasv_fd()
|
||||
* PURPOSE
|
||||
|
@ -102,6 +102,10 @@ parseconf_bool_array[] =
|
||||
{ "debug_ssl", &tunable_debug_ssl },
|
||||
{ "require_cert", &tunable_require_cert },
|
||||
{ "validate_cert", &tunable_validate_cert },
|
||||
{ "strict_ssl_read_eof", &tunable_strict_ssl_read_eof },
|
||||
{ "strict_ssl_write_shutdown", &tunable_strict_ssl_write_shutdown },
|
||||
{ "ssl_request_cert", &tunable_ssl_request_cert },
|
||||
{ "delete_failed_uploads", &tunable_delete_failed_uploads },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
33
postlogin.c
33
postlogin.c
@ -568,19 +568,22 @@ handle_pasv(struct vsf_session* p_sess, int is_epsv)
|
||||
retval = vsf_sysutil_bind(p_sess->pasv_listen_fd, s_p_sockaddr);
|
||||
if (!vsf_sysutil_retval_is_error(retval))
|
||||
{
|
||||
break;
|
||||
retval = vsf_sysutil_listen(p_sess->pasv_listen_fd, 1);
|
||||
if (!vsf_sysutil_retval_is_error(retval))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (vsf_sysutil_get_error() == kVSFSysUtilErrADDRINUSE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
die("vsf_sysutil_bind");
|
||||
die("vsf_sysutil_bind / listen");
|
||||
}
|
||||
if (!bind_retries)
|
||||
{
|
||||
die("vsf_sysutil_bind");
|
||||
}
|
||||
vsf_sysutil_listen(p_sess->pasv_listen_fd, 1);
|
||||
if (is_epsv)
|
||||
{
|
||||
str_alloc_text(&s_pasv_res_str, "Entering Extended Passive Mode (|||");
|
||||
@ -718,7 +721,10 @@ handle_retr(struct vsf_session* p_sess)
|
||||
}
|
||||
trans_ret = vsf_ftpdataio_transfer_file(p_sess, remote_fd,
|
||||
opened_file, 0, is_ascii);
|
||||
vsf_ftpdataio_dispose_transfer_fd(p_sess);
|
||||
if (vsf_ftpdataio_dispose_transfer_fd(p_sess) != 1 && trans_ret.retval == 0)
|
||||
{
|
||||
trans_ret.retval = -2;
|
||||
}
|
||||
p_sess->transfer_size = trans_ret.transferred;
|
||||
/* Log _after_ the blocking dispose call, so we get transfer times right */
|
||||
if (trans_ret.retval == 0)
|
||||
@ -863,7 +869,10 @@ handle_dir_common(struct vsf_session* p_sess, int full_details, int stat_cmd)
|
||||
}
|
||||
if (!stat_cmd)
|
||||
{
|
||||
vsf_ftpdataio_dispose_transfer_fd(p_sess);
|
||||
if (vsf_ftpdataio_dispose_transfer_fd(p_sess) != 1 && retval == 0)
|
||||
{
|
||||
retval = -1;
|
||||
}
|
||||
}
|
||||
if (stat_cmd)
|
||||
{
|
||||
@ -972,6 +981,8 @@ 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 success = 0;
|
||||
int created = 0;
|
||||
filesize_t offset = p_sess->restart_pos;
|
||||
p_sess->restart_pos = 0;
|
||||
if (!data_transfer_checks_ok(p_sess))
|
||||
@ -1018,6 +1029,7 @@ handle_upload_common(struct vsf_session* p_sess, int is_append, int is_unique)
|
||||
vsf_cmdio_write(p_sess, FTP_UPLOADFAIL, "Could not create file.");
|
||||
return;
|
||||
}
|
||||
created = 1;
|
||||
vsf_sysutil_fstat(new_file_fd, &s_p_statbuf);
|
||||
if (vsf_sysutil_statbuf_is_regfile(s_p_statbuf))
|
||||
{
|
||||
@ -1075,11 +1087,14 @@ 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);
|
||||
}
|
||||
vsf_ftpdataio_dispose_transfer_fd(p_sess);
|
||||
if (vsf_ftpdataio_dispose_transfer_fd(p_sess) != 1 && trans_ret.retval == 0)
|
||||
{
|
||||
trans_ret.retval = -2;
|
||||
}
|
||||
p_sess->transfer_size = trans_ret.transferred;
|
||||
/* XXX - handle failure, delete file? */
|
||||
if (trans_ret.retval == 0)
|
||||
{
|
||||
success = 1;
|
||||
vsf_log_do_log(p_sess, 1);
|
||||
}
|
||||
if (trans_ret.retval == -1)
|
||||
@ -1098,6 +1113,10 @@ handle_upload_common(struct vsf_session* p_sess, int is_append, int is_unique)
|
||||
port_pasv_cleanup_out:
|
||||
port_cleanup(p_sess);
|
||||
pasv_cleanup(p_sess);
|
||||
if (tunable_delete_failed_uploads && created && !success)
|
||||
{
|
||||
str_unlink(p_filename);
|
||||
}
|
||||
vsf_sysutil_close(new_file_fd);
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ vsf_privop_get_ftp_port_sock(struct vsf_session* p_sess)
|
||||
*/
|
||||
for (i = 0; i < 2; ++i)
|
||||
{
|
||||
double sleep_for;
|
||||
vsf_sysutil_sockaddr_clone(&p_sockaddr, p_sess->p_local_addr);
|
||||
vsf_sysutil_sockaddr_set_port(p_sockaddr, tunable_ftp_data_port);
|
||||
retval = vsf_sysutil_bind(s, p_sockaddr);
|
||||
@ -55,7 +56,7 @@ vsf_privop_get_ftp_port_sock(struct vsf_session* p_sess)
|
||||
{
|
||||
die("vsf_sysutil_bind");
|
||||
}
|
||||
double sleep_for = vsf_sysutil_get_random_byte();
|
||||
sleep_for = vsf_sysutil_get_random_byte();
|
||||
sleep_for /= 256.0;
|
||||
sleep_for += 1.0;
|
||||
vsf_sysutil_sleep(sleep_for);
|
||||
|
@ -51,11 +51,11 @@ ftp_write_str(const struct vsf_session* p_sess, const struct mystr* p_str,
|
||||
}
|
||||
|
||||
int
|
||||
ftp_read_data(const struct vsf_session* p_sess, char* p_buf, unsigned int len)
|
||||
ftp_read_data(struct vsf_session* p_sess, char* p_buf, unsigned int len)
|
||||
{
|
||||
if (p_sess->data_use_ssl)
|
||||
{
|
||||
return ssl_read(p_sess->p_data_ssl, p_buf, len);
|
||||
return ssl_read(p_sess, p_buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -12,8 +12,7 @@ enum EVSFRWTarget
|
||||
|
||||
int ftp_write_str(const struct vsf_session* p_sess, const struct mystr* p_str,
|
||||
enum EVSFRWTarget target);
|
||||
int ftp_read_data(const struct vsf_session* p_sess, char* p_buf,
|
||||
unsigned int len);
|
||||
int ftp_read_data(struct vsf_session* p_sess, char* p_buf, unsigned int len);
|
||||
int ftp_write_data(const struct vsf_session* p_sess, const char* p_buf,
|
||||
unsigned int len);
|
||||
void ftp_getline(const struct vsf_session* p_sess, struct mystr* p_str,
|
||||
|
136
ssl.c
136
ssl.c
@ -28,6 +28,7 @@
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <errno.h>
|
||||
|
||||
static char* get_ssl_error();
|
||||
static SSL* get_ssl(struct vsf_session* p_sess, int fd);
|
||||
@ -38,6 +39,8 @@ static long bio_callback(
|
||||
static int ssl_verify_callback(int verify_ok, X509_STORE_CTX* p_ctx);
|
||||
static int ssl_cert_digest(
|
||||
SSL* p_ssl, struct vsf_session* p_sess, struct mystr* p_str);
|
||||
static void maybe_log_shutdown_state(struct vsf_session* p_sess);
|
||||
static void maybe_log_ssl_error_state(struct vsf_session* p_sess, int ret);
|
||||
|
||||
static int ssl_inited;
|
||||
static struct mystr debug_str;
|
||||
@ -111,17 +114,23 @@ ssl_init(struct vsf_session* p_sess)
|
||||
{
|
||||
die("SSL: RNG is not seeded");
|
||||
}
|
||||
verify_option = SSL_VERIFY_PEER;
|
||||
if (tunable_ssl_request_cert)
|
||||
{
|
||||
verify_option |= SSL_VERIFY_PEER;
|
||||
}
|
||||
if (tunable_require_cert)
|
||||
{
|
||||
verify_option |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
|
||||
}
|
||||
SSL_CTX_set_verify(p_ctx, verify_option, ssl_verify_callback);
|
||||
if (tunable_ca_certs_file)
|
||||
if (verify_option)
|
||||
{
|
||||
if (!SSL_CTX_load_verify_locations(p_ctx, tunable_ca_certs_file, NULL))
|
||||
SSL_CTX_set_verify(p_ctx, verify_option, ssl_verify_callback);
|
||||
if (tunable_ca_certs_file)
|
||||
{
|
||||
die("SSL: could not load verify file");
|
||||
if (!SSL_CTX_load_verify_locations(p_ctx, tunable_ca_certs_file, NULL))
|
||||
{
|
||||
die("SSL: could not load verify file");
|
||||
}
|
||||
}
|
||||
}
|
||||
p_sess->p_ssl_ctx = p_ctx;
|
||||
@ -207,11 +216,12 @@ void
|
||||
ssl_getline(const struct vsf_session* p_sess, struct mystr* p_str,
|
||||
char end_char, char* p_buf, unsigned int buflen)
|
||||
{
|
||||
char* p_buf_start;
|
||||
if (buflen == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
char* p_buf_start = p_buf;
|
||||
p_buf_start = p_buf;
|
||||
p_buf[buflen - 1] = end_char;
|
||||
buflen--;
|
||||
while (1)
|
||||
@ -238,17 +248,30 @@ ssl_getline(const struct vsf_session* p_sess, struct mystr* p_str,
|
||||
}
|
||||
|
||||
int
|
||||
ssl_read(void* p_ssl, char* p_buf, unsigned int len)
|
||||
ssl_read(struct vsf_session* p_sess, char* p_buf, unsigned int len)
|
||||
{
|
||||
int retval;
|
||||
int err;
|
||||
SSL* p_ssl = p_sess->p_data_ssl;
|
||||
do
|
||||
{
|
||||
retval = SSL_read((SSL*) p_ssl, p_buf, len);
|
||||
err = SSL_get_error((SSL*) p_ssl, retval);
|
||||
retval = SSL_read(p_ssl, p_buf, len);
|
||||
err = SSL_get_error(p_ssl, retval);
|
||||
}
|
||||
while (retval < 0 && (err == SSL_ERROR_WANT_READ ||
|
||||
err == SSL_ERROR_WANT_WRITE));
|
||||
// If we hit an EOF, make sure it was from the peer, not injected by the
|
||||
// attacker.
|
||||
if (retval == 0 && SSL_get_shutdown(p_ssl) != SSL_RECEIVED_SHUTDOWN)
|
||||
{
|
||||
str_alloc_text(&debug_str, "Connection terminated without SSL shutdown "
|
||||
"- buggy client?");
|
||||
vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
|
||||
if (tunable_strict_ssl_read_eof)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -279,14 +302,93 @@ ssl_write_str(void* p_ssl, const struct mystr* p_str)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
maybe_log_shutdown_state(struct vsf_session* p_sess)
|
||||
{
|
||||
if (tunable_debug_ssl)
|
||||
{
|
||||
int ret = SSL_get_shutdown(p_sess->p_data_ssl);
|
||||
str_alloc_text(&debug_str, "SSL shutdown state is: ");
|
||||
if (ret == 0)
|
||||
{
|
||||
str_append_text(&debug_str, "NONE");
|
||||
}
|
||||
else if (ret == SSL_SENT_SHUTDOWN)
|
||||
{
|
||||
str_append_text(&debug_str, "SSL_SENT_SHUTDOWN");
|
||||
}
|
||||
else if (ret == SSL_RECEIVED_SHUTDOWN)
|
||||
{
|
||||
str_append_text(&debug_str, "SSL_RECEIVED_SHUTDOWN");
|
||||
}
|
||||
else
|
||||
{
|
||||
str_append_ulong(&debug_str, ret);
|
||||
}
|
||||
vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_log_ssl_error_state(struct vsf_session* p_sess, int ret)
|
||||
{
|
||||
if (tunable_debug_ssl)
|
||||
{
|
||||
str_alloc_text(&debug_str, "SSL ret: ");
|
||||
str_append_ulong(&debug_str, ret);
|
||||
str_append_text(&debug_str, ", SSL error: ");
|
||||
str_append_text(&debug_str, get_ssl_error());
|
||||
str_append_text(&debug_str, ", errno: ");
|
||||
str_append_ulong(&debug_str, errno);
|
||||
vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ssl_data_close(struct vsf_session* p_sess)
|
||||
{
|
||||
if (p_sess->p_data_ssl)
|
||||
int success = 1;
|
||||
SSL* p_ssl = p_sess->p_data_ssl;
|
||||
if (p_ssl)
|
||||
{
|
||||
SSL_free(p_sess->p_data_ssl);
|
||||
int ret;
|
||||
maybe_log_shutdown_state(p_sess);
|
||||
// This is a mess. Ideally, when we're the sender, we'd like to get to the
|
||||
// SSL_RECEIVED_SHUTDOWN state to get a cryptographic guarantee that the
|
||||
// peer received all the data and shut the connection down cleanly. It
|
||||
// doesn't matter hugely apart from logging, but it's a nagging detail.
|
||||
// Unfortunately, no FTP client I found was able to get sends into that
|
||||
// state, so the best we can do is issue SSL_shutdown but not check the
|
||||
// errors / returns. At least this enables the receiver to be sure of the
|
||||
// integrity of the send in terms of unwanted truncation.
|
||||
ret = SSL_shutdown(p_ssl);
|
||||
maybe_log_shutdown_state(p_sess);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = SSL_shutdown(p_ssl);
|
||||
maybe_log_shutdown_state(p_sess);
|
||||
if (ret != 1)
|
||||
{
|
||||
if (tunable_strict_ssl_write_shutdown)
|
||||
{
|
||||
success = 0;
|
||||
}
|
||||
maybe_log_shutdown_state(p_sess);
|
||||
maybe_log_ssl_error_state(p_sess, ret);
|
||||
}
|
||||
}
|
||||
else if (ret < 0)
|
||||
{
|
||||
if (tunable_strict_ssl_write_shutdown)
|
||||
{
|
||||
success = 0;
|
||||
}
|
||||
maybe_log_ssl_error_state(p_sess, ret);
|
||||
}
|
||||
SSL_free(p_ssl);
|
||||
p_sess->p_data_ssl = NULL;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
int
|
||||
@ -296,11 +398,12 @@ ssl_accept(struct vsf_session* p_sess, int fd)
|
||||
* protocol. If a client sends an unfortunately optional client cert then
|
||||
* we can check for a match between the control and data connections.
|
||||
*/
|
||||
SSL* p_ssl;
|
||||
if (p_sess->p_data_ssl != NULL)
|
||||
{
|
||||
die("p_data_ssl should be NULL.");
|
||||
}
|
||||
SSL* p_ssl = get_ssl(p_sess, fd);
|
||||
p_ssl = get_ssl(p_sess, fd);
|
||||
if (p_ssl == NULL)
|
||||
{
|
||||
return 0;
|
||||
@ -549,9 +652,9 @@ ssl_getline(const struct vsf_session* p_sess, struct mystr* p_str,
|
||||
}
|
||||
|
||||
int
|
||||
ssl_read(void* p_ssl, char* p_buf, unsigned int len)
|
||||
ssl_read(struct vsf_session* p_sess, char* p_buf, unsigned int len)
|
||||
{
|
||||
(void) p_ssl;
|
||||
(void) p_sess;
|
||||
(void) p_buf;
|
||||
(void) len;
|
||||
return -1;
|
||||
@ -582,10 +685,11 @@ ssl_accept(struct vsf_session* p_sess, int fd)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
ssl_data_close(struct vsf_session* p_sess)
|
||||
{
|
||||
(void) p_sess;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
|
4
ssl.h
4
ssl.h
@ -6,12 +6,12 @@ struct mystr;
|
||||
|
||||
void ssl_getline(const struct vsf_session* p_sess, struct mystr* p_str,
|
||||
char end_char, char* p_buf, unsigned int buflen);
|
||||
int ssl_read(void* p_ssl, char* p_buf, unsigned int len);
|
||||
int ssl_read(struct vsf_session* p_sess, char* p_buf, unsigned int len);
|
||||
int ssl_write(void* p_ssl, const char* p_buf, unsigned int len);
|
||||
int ssl_write_str(void* p_ssl, const struct mystr* p_str);
|
||||
void ssl_init(struct vsf_session* p_sess);
|
||||
int ssl_accept(struct vsf_session* p_sess, int fd);
|
||||
void ssl_data_close(struct vsf_session* p_sess);
|
||||
int ssl_data_close(struct vsf_session* p_sess);
|
||||
void ssl_comm_channel_init(struct vsf_session* p_sess);
|
||||
void handle_auth(struct vsf_session* p_sess);
|
||||
void handle_pbsz(struct vsf_session* p_sess);
|
||||
|
@ -130,7 +130,11 @@ vsf_standalone_main(void)
|
||||
die("could not bind listening IPv6 socket");
|
||||
}
|
||||
}
|
||||
vsf_sysutil_listen(listen_sock, VSFTP_LISTEN_BACKLOG);
|
||||
retval = vsf_sysutil_listen(listen_sock, VSFTP_LISTEN_BACKLOG);
|
||||
if (vsf_sysutil_retval_is_error(retval))
|
||||
{
|
||||
die("could not listen");
|
||||
}
|
||||
vsf_sysutil_sockaddr_alloc(&p_accept_addr);
|
||||
while (1)
|
||||
{
|
||||
|
12
sysutil.c
12
sysutil.c
@ -917,10 +917,11 @@ vsf_sysutil_isdigit(int the_char)
|
||||
char*
|
||||
vsf_sysutil_getcwd(char* p_dest, const unsigned int buf_size)
|
||||
{
|
||||
char* p_retval;
|
||||
if (buf_size == 0) {
|
||||
return p_dest;
|
||||
}
|
||||
char* p_retval = getcwd(p_dest, buf_size);
|
||||
p_retval = getcwd(p_dest, buf_size);
|
||||
p_dest[buf_size - 1] = '\0';
|
||||
return p_retval;
|
||||
}
|
||||
@ -1515,10 +1516,11 @@ vsf_sysutil_unlock_file(int fd)
|
||||
int
|
||||
vsf_sysutil_readlink(const char* p_filename, char* p_dest, unsigned int bufsiz)
|
||||
{
|
||||
int retval;
|
||||
if (bufsiz == 0) {
|
||||
return -1;
|
||||
}
|
||||
int retval = readlink(p_filename, p_dest, bufsiz - 1);
|
||||
retval = readlink(p_filename, p_dest, bufsiz - 1);
|
||||
if (retval < 0)
|
||||
{
|
||||
return retval;
|
||||
@ -1620,14 +1622,16 @@ vsf_sysutil_bind(int fd, const struct vsf_sysutil_sockaddr* p_sockptr)
|
||||
return bind(fd, p_sockaddr, len);
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
vsf_sysutil_listen(int fd, const unsigned int backlog)
|
||||
{
|
||||
int retval = listen(fd, backlog);
|
||||
if (retval != 0)
|
||||
if (vsf_sysutil_retval_is_error(retval) &&
|
||||
vsf_sysutil_get_error() != kVSFSysUtilErrADDRINUSE)
|
||||
{
|
||||
die("listen");
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Warning: callers of this function assume it does NOT make use of any
|
||||
|
@ -239,7 +239,7 @@ int vsf_sysutil_get_ipv6_sock(void);
|
||||
struct vsf_sysutil_socketpair_retval
|
||||
vsf_sysutil_unix_stream_socketpair(void);
|
||||
int vsf_sysutil_bind(int fd, const struct vsf_sysutil_sockaddr* p_sockptr);
|
||||
void vsf_sysutil_listen(int fd, const unsigned int backlog);
|
||||
int vsf_sysutil_listen(int fd, const unsigned int backlog);
|
||||
void vsf_sysutil_getsockname(int fd, struct vsf_sysutil_sockaddr** p_sockptr);
|
||||
void vsf_sysutil_getpeername(int fd, struct vsf_sysutil_sockaddr** p_sockptr);
|
||||
int vsf_sysutil_accept_timeout(int fd, struct vsf_sysutil_sockaddr* p_sockaddr,
|
||||
|
@ -74,6 +74,10 @@ int tunable_pasv_addr_resolve = 0;
|
||||
int tunable_debug_ssl = 0;
|
||||
int tunable_require_cert = 0;
|
||||
int tunable_validate_cert = 0;
|
||||
int tunable_strict_ssl_read_eof = 0;
|
||||
int tunable_strict_ssl_write_shutdown = 0;
|
||||
int tunable_ssl_request_cert = 1;
|
||||
int tunable_delete_failed_uploads = 0;
|
||||
|
||||
unsigned int tunable_accept_timeout = 60;
|
||||
unsigned int tunable_connect_timeout = 60;
|
||||
|
@ -70,6 +70,10 @@ extern int tunable_pasv_addr_resolve; /* DNS resolve pasv_addr */
|
||||
extern int tunable_debug_ssl; /* Verbose SSL logging */
|
||||
extern int tunable_require_cert; /* SSL client cert required */
|
||||
extern int tunable_validate_cert; /* SSL certs must be valid */
|
||||
extern int tunable_strict_ssl_read_eof; /* Need SSL_shutdown() on read */
|
||||
extern int tunable_strict_ssl_write_shutdown; /* Need SSL_shutdown() on write */
|
||||
extern int tunable_ssl_request_cert; /* Ask client for cert */
|
||||
extern int tunable_delete_failed_uploads; /* Delete an upload that failed */
|
||||
|
||||
/* Integer/numeric defines */
|
||||
extern unsigned int tunable_accept_timeout;
|
||||
|
@ -45,6 +45,7 @@ locate_library /usr/lib/libsec.sl && echo "-lsec";
|
||||
# Look for libcap (capabilities)
|
||||
locate_library /lib/libcap.so.1 && echo "/lib/libcap.so.1";
|
||||
locate_library /usr/lib/libcap.so && echo "-lcap";
|
||||
locate_library /lib/libcap.so && echo "-lcap";
|
||||
|
||||
# Solaris needs this for nanosleep()..
|
||||
locate_library /lib/libposix4.so && echo "-lposix4";
|
||||
|
@ -167,6 +167,11 @@ Default: NO (but the sample config file enables it)
|
||||
If true, OpenSSL connection diagnostics are dumped to the vsftpd log file.
|
||||
(Added in v2.0.6).
|
||||
|
||||
Default: NO
|
||||
.TP
|
||||
.B delete_failed_uploads
|
||||
If true, any failed upload files are deleted. (Added in v2.0.7).
|
||||
|
||||
Default: NO
|
||||
.TP
|
||||
.B deny_email_enable
|
||||
@ -445,6 +450,14 @@ OpenSSL library.
|
||||
|
||||
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
|
||||
should not cause any trouble at all, but IBM zOS seems to have issues.
|
||||
(New in v2.0.7).
|
||||
|
||||
Default: YES
|
||||
.TP
|
||||
.B ssl_sslv2
|
||||
Only applies if
|
||||
.BR ssl_enable
|
||||
@ -469,6 +482,23 @@ TLS v1 connections are preferred.
|
||||
|
||||
Default: YES
|
||||
.TP
|
||||
.B strict_ssl_read_eof
|
||||
If enabled, SSL data uploads are required to terminate via SSL, not an
|
||||
EOF on the socket. This option is required to be sure that an attacker did
|
||||
not terminate an upload prematurely with a faked TCP FIN. Unfortunately, it
|
||||
is not enabled by default because so few clients get it right. (New in v2.0.7).
|
||||
|
||||
Default: NO
|
||||
.TP
|
||||
.B strict_ssl_write_shutdown
|
||||
If enabled, SSL data downloads are required to terminate via SSL, not an
|
||||
EOF on the socket. This is off by default as I was unable to find a single
|
||||
FTP client that does this. It is minor. All it affects is our ability to tell
|
||||
whether the client confirmed full receipt of the file. Even without this option,
|
||||
the client is able to check the integrity of the download. (New in v2.0.7).
|
||||
|
||||
Default: NO
|
||||
.TP
|
||||
.B syslog_enable
|
||||
If enabled, then any log output which would have gone to /var/log/vsftpd.log
|
||||
goes to the system log instead. Logging is done under the FTPD facility.
|
||||
@ -915,7 +945,7 @@ Default: /usr/share/empty
|
||||
.TP
|
||||
.B ssl_ciphers
|
||||
This option can be used to select which SSL ciphers vsftpd will allow for
|
||||
encrpyted SSL connections. See the
|
||||
encrypted SSL connections. See the
|
||||
.BR ciphers
|
||||
man page for further details. Note that restricting ciphers can be a useful
|
||||
security precaution as it prevents malicious remote parties forcing a cipher
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef VSF_VERSION_H
|
||||
#define VSF_VERSION_H
|
||||
|
||||
#define VSF_VERSION "2.0.6"
|
||||
#define VSF_VERSION "2.0.7"
|
||||
|
||||
#endif /* VSF_VERSION_H */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user