mirror of
https://github.com/InfrastructureServices/vsftpd.git
synced 2025-04-19 01:24:02 +03:00
Updated to v3.0.1
This commit is contained in:
parent
8ab4684483
commit
48344724c6
14
Changelog
14
Changelog
@ -1323,3 +1323,17 @@ protocol synchronization issues.
|
||||
|
||||
At this point: v3.0.0 released!
|
||||
===============================
|
||||
|
||||
- Fix some seccomp related build errors on certain CentOS and Debian versions.
|
||||
- Seccomp filter sandbox: missing munmap() -- oops. Did you know that qsort()
|
||||
opens and maps /proc/meminfo but only for larger item counts?
|
||||
- Seccomp filter sandbox: deny socket() gracefully for text_userdb_names.
|
||||
- Fix various NULL crashes with nonsensical config settings. Noted by Tianyin Xu
|
||||
<tixu@cs.ucsd.edu>.
|
||||
- Force cast to unsigned char in is* char functions.
|
||||
- Fix harmless integer issues in strlist.c.
|
||||
- Started on a (possibly ill-advised?) crusade to compile cleanly with
|
||||
Wconversion. Decided to suspend the effort half-way through.
|
||||
|
||||
At this point: v3.0.1 released!
|
||||
===============================
|
||||
|
2
README
2
README
@ -1,4 +1,4 @@
|
||||
This is vsftpd, version 3.0.0
|
||||
This is vsftpd, version 3.0.1
|
||||
Author: Chris Evans
|
||||
Contact: scarybeasts@gmail.com
|
||||
Website: http://vsftpd.beasts.org/
|
||||
|
7
banner.c
7
banner.c
@ -53,8 +53,11 @@ vsf_banner_dir_changed(struct vsf_session* p_sess, int ftpcode)
|
||||
*/
|
||||
{
|
||||
struct mystr msg_file_str = INIT_MYSTR;
|
||||
(void) str_fileread(&msg_file_str, tunable_message_file,
|
||||
VSFTP_MAX_MSGFILE_SIZE);
|
||||
if (tunable_message_file)
|
||||
{
|
||||
(void) str_fileread(&msg_file_str, tunable_message_file,
|
||||
VSFTP_MAX_MSGFILE_SIZE);
|
||||
}
|
||||
vsf_banner_write(p_sess, &msg_file_str, ftpcode);
|
||||
str_free(&msg_file_str);
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ str_fileread(struct mystr* p_str, const char* p_filename, unsigned int maxsize)
|
||||
{
|
||||
die("read size mismatch");
|
||||
}
|
||||
str_alloc_memchunk(p_str, p_sec_buf, size);
|
||||
str_alloc_memchunk(p_str, p_sec_buf, (unsigned int) size);
|
||||
}
|
||||
free_out:
|
||||
vsf_sysutil_free(p_stat);
|
||||
|
2
hash.c
2
hash.c
@ -42,7 +42,7 @@ hash_alloc(unsigned int buckets, unsigned int key_size,
|
||||
p_hash->key_size = key_size;
|
||||
p_hash->value_size = value_size;
|
||||
p_hash->hash_func = hash_func;
|
||||
size = sizeof(struct hash_node*) * buckets;
|
||||
size = (unsigned int) sizeof(struct hash_node*) * buckets;
|
||||
p_hash->p_nodes = vsf_sysutil_malloc(size);
|
||||
vsf_sysutil_memclr(p_hash->p_nodes, size);
|
||||
return p_hash;
|
||||
|
16
logging.c
16
logging.c
@ -30,7 +30,6 @@ static void vsf_log_do_log_to_file(int fd, struct mystr* p_str);
|
||||
void
|
||||
vsf_log_init(struct vsf_session* p_sess)
|
||||
{
|
||||
int retval;
|
||||
if (tunable_syslog_enable || tunable_tcp_wrappers)
|
||||
{
|
||||
vsf_sysutil_openlog(1);
|
||||
@ -41,7 +40,12 @@ vsf_log_init(struct vsf_session* p_sess)
|
||||
}
|
||||
if (tunable_dual_log_enable || tunable_xferlog_std_format)
|
||||
{
|
||||
retval = vsf_sysutil_create_or_open_file_append(tunable_xferlog_file, 0600);
|
||||
int retval = -1;
|
||||
if (tunable_xferlog_file)
|
||||
{
|
||||
retval = vsf_sysutil_create_or_open_file_append(tunable_xferlog_file,
|
||||
0600);
|
||||
}
|
||||
if (vsf_sysutil_retval_is_error(retval))
|
||||
{
|
||||
die2("failed to open xferlog log file:", tunable_xferlog_file);
|
||||
@ -52,8 +56,12 @@ vsf_log_init(struct vsf_session* p_sess)
|
||||
{
|
||||
if (!tunable_syslog_enable)
|
||||
{
|
||||
retval = vsf_sysutil_create_or_open_file_append(tunable_vsftpd_log_file,
|
||||
0600);
|
||||
int retval = -1;
|
||||
if (tunable_vsftpd_log_file)
|
||||
{
|
||||
retval = vsf_sysutil_create_or_open_file_append(tunable_vsftpd_log_file,
|
||||
0600);
|
||||
}
|
||||
if (vsf_sysutil_retval_is_error(retval))
|
||||
{
|
||||
die2("failed to open vsftpd log file:", tunable_vsftpd_log_file);
|
||||
|
23
ls.c
23
ls.c
@ -88,7 +88,6 @@ vsf_ls_populate_dir_list(struct mystr_list* p_list,
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
int len;
|
||||
static struct mystr s_next_filename_str;
|
||||
static struct mystr s_next_path_and_filename_str;
|
||||
static struct vsf_sysutil_statbuf* s_p_statbuf;
|
||||
@ -97,18 +96,20 @@ vsf_ls_populate_dir_list(struct mystr_list* p_list,
|
||||
{
|
||||
break;
|
||||
}
|
||||
len = str_getlen(&s_next_filename_str);
|
||||
if (len > 0 && str_get_char_at(&s_next_filename_str, 0) == '.')
|
||||
{
|
||||
if (!a_option && !tunable_force_dot_files)
|
||||
unsigned int len = str_getlen(&s_next_filename_str);
|
||||
if (len > 0 && str_get_char_at(&s_next_filename_str, 0) == '.')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!a_option &&
|
||||
((len == 2 && str_get_char_at(&s_next_filename_str, 1) == '.') ||
|
||||
len == 1))
|
||||
{
|
||||
continue;
|
||||
if (!a_option && !tunable_force_dot_files)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!a_option &&
|
||||
((len == 2 && str_get_char_at(&s_next_filename_str, 1) == '.') ||
|
||||
len == 1))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Don't show hidden directory entries */
|
||||
|
39
main.c
39
main.c
@ -200,8 +200,12 @@ main(int argc, const char* argv[])
|
||||
}
|
||||
if (tunable_deny_email_enable)
|
||||
{
|
||||
int retval = str_fileread(&the_session.banned_email_str,
|
||||
tunable_banned_email_file, VSFTP_CONF_FILE_MAX);
|
||||
int retval = -1;
|
||||
if (tunable_banned_email_file)
|
||||
{
|
||||
retval = str_fileread(&the_session.banned_email_str,
|
||||
tunable_banned_email_file, VSFTP_CONF_FILE_MAX);
|
||||
}
|
||||
if (vsf_sysutil_retval_is_error(retval))
|
||||
{
|
||||
die2("cannot read anon e-mail list file:", tunable_banned_email_file);
|
||||
@ -218,9 +222,13 @@ main(int argc, const char* argv[])
|
||||
}
|
||||
if (tunable_secure_email_list_enable)
|
||||
{
|
||||
int retval = str_fileread(&the_session.email_passwords_str,
|
||||
tunable_email_password_file,
|
||||
VSFTP_CONF_FILE_MAX);
|
||||
int retval = -1;
|
||||
if (tunable_email_password_file)
|
||||
{
|
||||
retval = str_fileread(&the_session.email_passwords_str,
|
||||
tunable_email_password_file,
|
||||
VSFTP_CONF_FILE_MAX);
|
||||
}
|
||||
if (vsf_sysutil_retval_is_error(retval))
|
||||
{
|
||||
die2("cannot read email passwords file:", tunable_email_password_file);
|
||||
@ -329,8 +337,11 @@ session_init(struct vsf_session* p_sess)
|
||||
/* If anonymous mode is active, fetch the uid of the anonymous user */
|
||||
if (tunable_anonymous_enable)
|
||||
{
|
||||
const struct vsf_sysutil_user* p_user =
|
||||
vsf_sysutil_getpwnam(tunable_ftp_username);
|
||||
const struct vsf_sysutil_user* p_user = 0;
|
||||
if (tunable_ftp_username)
|
||||
{
|
||||
p_user = vsf_sysutil_getpwnam(tunable_ftp_username);
|
||||
}
|
||||
if (p_user == 0)
|
||||
{
|
||||
die2("vsftpd: cannot locate user specified in 'ftp_username':",
|
||||
@ -340,8 +351,11 @@ session_init(struct vsf_session* p_sess)
|
||||
}
|
||||
if (tunable_guest_enable)
|
||||
{
|
||||
const struct vsf_sysutil_user* p_user =
|
||||
vsf_sysutil_getpwnam(tunable_guest_username);
|
||||
const struct vsf_sysutil_user* p_user = 0;
|
||||
if (tunable_guest_username)
|
||||
{
|
||||
p_user = vsf_sysutil_getpwnam(tunable_guest_username);
|
||||
}
|
||||
if (p_user == 0)
|
||||
{
|
||||
die2("vsftpd: cannot locate user specified in 'guest_username':",
|
||||
@ -351,8 +365,11 @@ session_init(struct vsf_session* p_sess)
|
||||
}
|
||||
if (tunable_chown_uploads)
|
||||
{
|
||||
const struct vsf_sysutil_user* p_user =
|
||||
vsf_sysutil_getpwnam(tunable_chown_username);
|
||||
const struct vsf_sysutil_user* p_user = 0;
|
||||
if (tunable_chown_username)
|
||||
{
|
||||
p_user = vsf_sysutil_getpwnam(tunable_chown_username);
|
||||
}
|
||||
if (p_user == 0)
|
||||
{
|
||||
die2("vsftpd: cannot locate user specified in 'chown_username':",
|
||||
|
@ -76,7 +76,10 @@ one_process_start(void* p_arg)
|
||||
{
|
||||
struct mystr user_name = INIT_MYSTR;
|
||||
struct mystr chdir_str = INIT_MYSTR;
|
||||
str_alloc_text(&user_name, tunable_ftp_username);
|
||||
if (tunable_ftp_username)
|
||||
{
|
||||
str_alloc_text(&user_name, tunable_ftp_username);
|
||||
}
|
||||
if (tunable_anon_root)
|
||||
{
|
||||
str_alloc_text(&chdir_str, tunable_anon_root);
|
||||
|
@ -344,7 +344,8 @@ vsf_parseconf_load_setting(const char* p_setting, int errs_fatal)
|
||||
}
|
||||
else
|
||||
{
|
||||
*(p_uint_setting->p_variable) = str_atoi(&s_value_str);
|
||||
/* TODO: we could reject negatives instead of converting them? */
|
||||
*(p_uint_setting->p_variable) = (unsigned int) str_atoi(&s_value_str);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -974,8 +974,7 @@ handle_port(struct vsf_session* p_sess)
|
||||
vsf_cmdio_write(p_sess, FTP_BADCMD, "Illegal PORT command.");
|
||||
return;
|
||||
}
|
||||
the_port = vals[4] << 8;
|
||||
the_port |= vals[5];
|
||||
the_port = (unsigned short) ((vals[4] << 8) | vals[5]);
|
||||
vsf_sysutil_sockaddr_clone(&p_sess->p_port_sockaddr, p_sess->p_local_addr);
|
||||
vsf_sysutil_sockaddr_set_ipv4addr(p_sess->p_port_sockaddr, vals);
|
||||
vsf_sysutil_sockaddr_set_port(p_sess->p_port_sockaddr, the_port);
|
||||
@ -1736,7 +1735,7 @@ handle_eprt(struct vsf_session* p_sess)
|
||||
{
|
||||
if (!vsf_sysutil_sockaddr_addr_equal(p_sess->p_remote_addr,
|
||||
p_sess->p_port_sockaddr) ||
|
||||
vsf_sysutil_is_port_reserved(port))
|
||||
vsf_sysutil_is_port_reserved((unsigned short) port))
|
||||
{
|
||||
vsf_cmdio_write(p_sess, FTP_BADCMD, "Illegal EPRT command.");
|
||||
port_cleanup(p_sess);
|
||||
|
@ -96,8 +96,14 @@ minimize_privilege(struct vsf_session* p_sess)
|
||||
unsigned int caps = 0;
|
||||
struct mystr user_str = INIT_MYSTR;
|
||||
struct mystr dir_str = INIT_MYSTR;
|
||||
str_alloc_text(&user_str, tunable_nopriv_user);
|
||||
str_alloc_text(&dir_str, tunable_secure_chroot_dir);
|
||||
if (tunable_nopriv_user)
|
||||
{
|
||||
str_alloc_text(&user_str, tunable_nopriv_user);
|
||||
}
|
||||
if (tunable_secure_chroot_dir)
|
||||
{
|
||||
str_alloc_text(&dir_str, tunable_secure_chroot_dir);
|
||||
}
|
||||
if (tunable_chown_uploads)
|
||||
{
|
||||
caps |= kCapabilityCAP_CHOWN;
|
||||
|
17
privops.c
17
privops.c
@ -41,7 +41,7 @@ vsf_privop_get_ftp_port_sock(struct vsf_session* p_sess,
|
||||
int retval;
|
||||
int i;
|
||||
int s = vsf_sysutil_get_ipsock(p_sess->p_local_addr);
|
||||
int port = 0;
|
||||
unsigned short port = 0;
|
||||
if (p_sess->pasv_listen_fd != -1)
|
||||
{
|
||||
die("listed fd is active?");
|
||||
@ -52,7 +52,7 @@ vsf_privop_get_ftp_port_sock(struct vsf_session* p_sess,
|
||||
}
|
||||
if (tunable_connect_from_port_20)
|
||||
{
|
||||
port = tunable_ftp_data_port;
|
||||
port = (unsigned short) tunable_ftp_data_port;
|
||||
}
|
||||
vsf_sysutil_activate_reuseaddr(s);
|
||||
/* A report of failure here on Solaris, presumably buggy address reuse
|
||||
@ -133,11 +133,11 @@ vsf_privop_pasv_listen(struct vsf_session* p_sess)
|
||||
|
||||
if (tunable_pasv_min_port > min_port && tunable_pasv_min_port <= max_port)
|
||||
{
|
||||
min_port = tunable_pasv_min_port;
|
||||
min_port = (unsigned short) tunable_pasv_min_port;
|
||||
}
|
||||
if (tunable_pasv_max_port >= min_port && tunable_pasv_max_port < max_port)
|
||||
{
|
||||
max_port = tunable_pasv_max_port;
|
||||
max_port = (unsigned short) tunable_pasv_max_port;
|
||||
}
|
||||
|
||||
while (--bind_retries)
|
||||
@ -145,8 +145,8 @@ vsf_privop_pasv_listen(struct vsf_session* p_sess)
|
||||
int retval;
|
||||
double scaled_port;
|
||||
the_port = vsf_sysutil_get_random_byte();
|
||||
the_port <<= 8;
|
||||
the_port |= vsf_sysutil_get_random_byte();
|
||||
the_port = (unsigned short) (the_port << 8);
|
||||
the_port = (unsigned short) (the_port | vsf_sysutil_get_random_byte());
|
||||
scaled_port = (double) min_port;
|
||||
scaled_port += ((double) the_port / (double) 65536) *
|
||||
((double) max_port - min_port + 1);
|
||||
@ -367,7 +367,10 @@ handle_anonymous_login(struct vsf_session* p_sess,
|
||||
str_replace_char(&p_sess->anon_pass_str, '\n', '?');
|
||||
{
|
||||
struct mystr ftp_username_str = INIT_MYSTR;
|
||||
str_alloc_text(&ftp_username_str, tunable_ftp_username);
|
||||
if (tunable_ftp_username)
|
||||
{
|
||||
str_alloc_text(&ftp_username_str, tunable_ftp_username);
|
||||
}
|
||||
setup_username_globals(p_sess, &ftp_username_str);
|
||||
str_free(&ftp_username_str);
|
||||
}
|
||||
|
@ -33,6 +33,10 @@
|
||||
|
||||
/* #define DEBUG_SIGSYS 1 */
|
||||
|
||||
#ifndef PR_SET_SECCOMP
|
||||
#define PR_SET_SECCOMP 22
|
||||
#endif
|
||||
|
||||
#ifndef PR_SET_NO_NEW_PRIVS
|
||||
#define PR_SET_NO_NEW_PRIVS 38
|
||||
#endif
|
||||
@ -45,6 +49,14 @@
|
||||
#define O_LARGEFILE 00100000
|
||||
#endif
|
||||
|
||||
#ifndef O_DIRECTORY
|
||||
#define O_DIRECTORY 00200000
|
||||
#endif
|
||||
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 002000000
|
||||
#endif
|
||||
|
||||
#define kMaxSyscalls 100
|
||||
|
||||
#ifdef DEBUG_SIGSYS
|
||||
@ -67,6 +79,7 @@ static size_t s_1_arg_validations;
|
||||
static size_t s_2_arg_validations;
|
||||
static size_t s_3_arg_validations;
|
||||
static int s_syscalls[kMaxSyscalls];
|
||||
static int s_errnos[kMaxSyscalls];
|
||||
static int s_args_1[kMaxSyscalls];
|
||||
static int s_vals_1[kMaxSyscalls];
|
||||
static int s_args_2[kMaxSyscalls];
|
||||
@ -85,6 +98,26 @@ allow_nr(int nr)
|
||||
{
|
||||
bug("negative syscall");
|
||||
}
|
||||
s_errnos[s_syscall_index] = 0;
|
||||
s_syscalls[s_syscall_index++] = nr;
|
||||
}
|
||||
|
||||
static void
|
||||
reject_nr(int nr, int errcode)
|
||||
{
|
||||
if (s_syscall_index >= kMaxSyscalls)
|
||||
{
|
||||
bug("out of syscall space");
|
||||
}
|
||||
if (nr < 0)
|
||||
{
|
||||
bug("negative syscall");
|
||||
}
|
||||
if (errcode < 0 || errcode > 255)
|
||||
{
|
||||
bug("bad errcode");
|
||||
}
|
||||
s_errnos[s_syscall_index] = errcode;
|
||||
s_syscalls[s_syscall_index++] = nr;
|
||||
}
|
||||
|
||||
@ -105,6 +138,7 @@ allow_nr_1_arg_match(int nr, int arg, int val)
|
||||
}
|
||||
s_args_1[s_syscall_index] = arg;
|
||||
s_vals_1[s_syscall_index] = val;
|
||||
s_errnos[s_syscall_index] = 0;
|
||||
s_syscalls[s_syscall_index++] = nr;
|
||||
s_1_arg_validations++;
|
||||
}
|
||||
@ -126,6 +160,7 @@ allow_nr_1_arg_mask(int nr, int arg, int val)
|
||||
}
|
||||
s_args_1[s_syscall_index] = 100 + arg;
|
||||
s_vals_1[s_syscall_index] = val;
|
||||
s_errnos[s_syscall_index] = 0;
|
||||
s_syscalls[s_syscall_index++] = nr;
|
||||
s_1_arg_validations++;
|
||||
}
|
||||
@ -153,6 +188,7 @@ allow_nr_2_arg_match(int nr, int arg1, int val1, int arg2, int val2)
|
||||
s_vals_1[s_syscall_index] = val1;
|
||||
s_args_2[s_syscall_index] = arg2;
|
||||
s_vals_2[s_syscall_index] = val2;
|
||||
s_errnos[s_syscall_index] = 0;
|
||||
s_syscalls[s_syscall_index++] = nr;
|
||||
s_2_arg_validations++;
|
||||
}
|
||||
@ -180,6 +216,7 @@ allow_nr_2_arg_mask_match(int nr, int arg1, int val1, int arg2, int val2)
|
||||
s_vals_1[s_syscall_index] = val1;
|
||||
s_args_2[s_syscall_index] = arg2;
|
||||
s_vals_2[s_syscall_index] = val2;
|
||||
s_errnos[s_syscall_index] = 0;
|
||||
s_syscalls[s_syscall_index++] = nr;
|
||||
s_2_arg_validations++;
|
||||
}
|
||||
@ -214,6 +251,7 @@ allow_nr_3_arg_match(int nr, int arg1, int val1, int arg2, int val2, int arg3,
|
||||
s_vals_2[s_syscall_index] = val2;
|
||||
s_args_3[s_syscall_index] = arg3;
|
||||
s_vals_3[s_syscall_index] = val3;
|
||||
s_errnos[s_syscall_index] = 0;
|
||||
s_syscalls[s_syscall_index++] = nr;
|
||||
s_3_arg_validations++;
|
||||
}
|
||||
@ -256,6 +294,7 @@ seccomp_sandbox_setup_base()
|
||||
3, PROT_READ|PROT_WRITE,
|
||||
4, MAP_PRIVATE|MAP_ANON);
|
||||
allow_nr_1_arg_mask(__NR_mprotect, 3, PROT_READ);
|
||||
allow_nr(__NR_munmap);
|
||||
allow_nr(__NR_brk);
|
||||
|
||||
/* Misc simple low-risk calls. */
|
||||
@ -402,8 +441,8 @@ seccomp_sandbox_setup_postlogin(const struct vsf_session* p_sess)
|
||||
|
||||
if (tunable_text_userdb_names)
|
||||
{
|
||||
reject_nr(__NR_socket, EACCES);
|
||||
allow_nr_2_arg_match(__NR_mmap, 3, PROT_READ, 4, MAP_SHARED);
|
||||
allow_nr(__NR_munmap);
|
||||
}
|
||||
|
||||
if (tunable_write_enable)
|
||||
@ -565,8 +604,16 @@ seccomp_sandbox_lockdown()
|
||||
p_filter->code = BPF_RET+BPF_K;
|
||||
p_filter->jt = 0;
|
||||
p_filter->jf = 0;
|
||||
/* SECCOMP_RET_ALLOW */
|
||||
p_filter->k = 0x7fff0000;
|
||||
if (!s_errnos[i])
|
||||
{
|
||||
/* SECCOMP_RET_ALLOW */
|
||||
p_filter->k = 0x7fff0000;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* SECCOMP_RET_ERRNO */
|
||||
p_filter->k = 0x00050000 + s_errnos[i];
|
||||
}
|
||||
p_filter++;
|
||||
if (s_args_1[i])
|
||||
{
|
||||
|
@ -80,7 +80,8 @@ vsf_standalone_main(void)
|
||||
{
|
||||
struct vsf_sysutil_sockaddr* p_sockaddr = 0;
|
||||
vsf_sysutil_sockaddr_alloc_ipv4(&p_sockaddr);
|
||||
vsf_sysutil_sockaddr_set_port(p_sockaddr, tunable_listen_port);
|
||||
vsf_sysutil_sockaddr_set_port(p_sockaddr,
|
||||
(unsigned short) tunable_listen_port);
|
||||
if (!tunable_listen_address)
|
||||
{
|
||||
vsf_sysutil_sockaddr_set_any(p_sockaddr);
|
||||
@ -103,7 +104,8 @@ vsf_standalone_main(void)
|
||||
{
|
||||
struct vsf_sysutil_sockaddr* p_sockaddr = 0;
|
||||
vsf_sysutil_sockaddr_alloc_ipv6(&p_sockaddr);
|
||||
vsf_sysutil_sockaddr_set_port(p_sockaddr, tunable_listen_port);
|
||||
vsf_sysutil_sockaddr_set_port(p_sockaddr,
|
||||
(unsigned short) tunable_listen_port);
|
||||
if (!tunable_listen_address6)
|
||||
{
|
||||
vsf_sysutil_sockaddr_set_any(p_sockaddr);
|
||||
@ -272,7 +274,7 @@ hash_ip(unsigned int buckets, void* p_key)
|
||||
unsigned int i;
|
||||
for (i = 0; i < s_ipaddr_size; ++i)
|
||||
{
|
||||
val ^= p_raw_ip[i] << shift;
|
||||
val = val ^ (unsigned int) (p_raw_ip[i] << shift);
|
||||
shift -= 8;
|
||||
if (shift < 0)
|
||||
{
|
||||
|
2
str.c
2
str.c
@ -289,7 +289,7 @@ str_upper(struct mystr* p_str)
|
||||
unsigned int i;
|
||||
for (i=0; i < p_str->len; i++)
|
||||
{
|
||||
p_str->p_buf[i] = vsf_sysutil_toupper(p_str->p_buf[i]);
|
||||
p_str->p_buf[i] = (char) vsf_sysutil_toupper(p_str->p_buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
18
strlist.c
18
strlist.c
@ -22,6 +22,8 @@ struct mystr_list_node
|
||||
};
|
||||
|
||||
/* File locals */
|
||||
static const unsigned int kMaxStrlist = 10 * 1000 * 1000;
|
||||
|
||||
static struct mystr s_null_str;
|
||||
|
||||
static int sort_compare_func(const void* p1, const void* p2);
|
||||
@ -46,7 +48,7 @@ str_list_free(struct mystr_list* p_list)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
unsigned int
|
||||
str_list_get_length(const struct mystr_list* p_list)
|
||||
{
|
||||
return p_list->list_len;
|
||||
@ -78,15 +80,19 @@ str_list_add(struct mystr_list* p_list, const struct mystr* p_str,
|
||||
if (p_list->alloc_len == 0)
|
||||
{
|
||||
p_list->alloc_len = 32;
|
||||
p_list->p_nodes = vsf_sysutil_malloc(p_list->alloc_len *
|
||||
sizeof(struct mystr_list_node));
|
||||
p_list->p_nodes = vsf_sysutil_malloc(
|
||||
p_list->alloc_len * (unsigned int) sizeof(struct mystr_list_node));
|
||||
}
|
||||
else
|
||||
{
|
||||
p_list->alloc_len *= 2;
|
||||
p_list->p_nodes = vsf_sysutil_realloc(p_list->p_nodes,
|
||||
p_list->alloc_len *
|
||||
sizeof(struct mystr_list_node));
|
||||
if (p_list->alloc_len > kMaxStrlist)
|
||||
{
|
||||
die("excessive strlist");
|
||||
}
|
||||
p_list->p_nodes = vsf_sysutil_realloc(
|
||||
p_list->p_nodes,
|
||||
p_list->alloc_len * (unsigned int) sizeof(struct mystr_list_node));
|
||||
}
|
||||
}
|
||||
p_node = &p_list->p_nodes[p_list->list_len];
|
||||
|
@ -21,7 +21,7 @@ void str_list_add(struct mystr_list* p_list, const struct mystr* p_str,
|
||||
const struct mystr* p_sort_key_str);
|
||||
void str_list_sort(struct mystr_list* p_list, int reverse);
|
||||
|
||||
int str_list_get_length(const struct mystr_list* p_list);
|
||||
unsigned int str_list_get_length(const struct mystr_list* p_list);
|
||||
int str_list_contains_str(const struct mystr_list* p_list,
|
||||
const struct mystr* p_str);
|
||||
|
||||
|
@ -322,7 +322,7 @@ vsf_sysdep_check_auth(struct mystr* p_user_str,
|
||||
const struct mystr* p_pass_str,
|
||||
const struct mystr* p_remote_host)
|
||||
{
|
||||
int retval;
|
||||
int retval = -1;
|
||||
pam_item_t item;
|
||||
const char* pam_user_name = 0;
|
||||
struct pam_conv the_conv =
|
||||
@ -335,8 +335,11 @@ vsf_sysdep_check_auth(struct mystr* p_user_str,
|
||||
bug("vsf_sysdep_check_auth");
|
||||
}
|
||||
str_copy(&s_pword_str, p_pass_str);
|
||||
retval = pam_start(tunable_pam_service_name,
|
||||
str_getbuf(p_user_str), &the_conv, &s_pamh);
|
||||
if (tunable_pam_service_name)
|
||||
{
|
||||
retval = pam_start(tunable_pam_service_name,
|
||||
str_getbuf(p_user_str), &the_conv, &s_pamh);
|
||||
}
|
||||
if (retval != PAM_SUCCESS)
|
||||
{
|
||||
s_pamh = 0;
|
||||
|
10
sysutil.c
10
sysutil.c
@ -909,13 +909,13 @@ vsf_sysutil_octal_to_uint(const char* p_str)
|
||||
int
|
||||
vsf_sysutil_toupper(int the_char)
|
||||
{
|
||||
return toupper(the_char);
|
||||
return toupper((unsigned char) the_char);
|
||||
}
|
||||
|
||||
int
|
||||
vsf_sysutil_isspace(int the_char)
|
||||
{
|
||||
return isspace(the_char);
|
||||
return isspace((unsigned char) the_char);
|
||||
}
|
||||
|
||||
int
|
||||
@ -943,13 +943,13 @@ vsf_sysutil_isprint(int the_char)
|
||||
int
|
||||
vsf_sysutil_isalnum(int the_char)
|
||||
{
|
||||
return isalnum(the_char);
|
||||
return isalnum((unsigned char) the_char);
|
||||
}
|
||||
|
||||
int
|
||||
vsf_sysutil_isdigit(int the_char)
|
||||
{
|
||||
return isdigit(the_char);
|
||||
return isdigit((unsigned char) the_char);
|
||||
}
|
||||
|
||||
char*
|
||||
@ -2790,7 +2790,7 @@ vsf_sysutil_getuid(void)
|
||||
}
|
||||
|
||||
void
|
||||
vsf_sysutil_set_address_space_limit(long bytes)
|
||||
vsf_sysutil_set_address_space_limit(unsigned long bytes)
|
||||
{
|
||||
/* Unfortunately, OpenBSD is missing RLIMIT_AS. */
|
||||
#ifdef RLIMIT_AS
|
||||
|
@ -344,7 +344,7 @@ void vsf_sysutil_sleep(double seconds);
|
||||
int vsf_sysutil_setmodtime(const char* p_file, long the_time, int is_localtime);
|
||||
|
||||
/* Limits */
|
||||
void vsf_sysutil_set_address_space_limit(long bytes);
|
||||
void vsf_sysutil_set_address_space_limit(unsigned long bytes);
|
||||
void vsf_sysutil_set_no_fds(void);
|
||||
void vsf_sysutil_set_no_procs(void);
|
||||
|
||||
|
40
twoprocess.c
40
twoprocess.c
@ -124,8 +124,12 @@ vsf_two_process_start(struct vsf_session* p_sess)
|
||||
}
|
||||
if (tunable_local_enable && tunable_userlist_enable)
|
||||
{
|
||||
int retval = str_fileread(&p_sess->userlist_str, tunable_userlist_file,
|
||||
VSFTP_CONF_FILE_MAX);
|
||||
int retval = -1;
|
||||
if (tunable_userlist_file)
|
||||
{
|
||||
retval = str_fileread(&p_sess->userlist_str, tunable_userlist_file,
|
||||
VSFTP_CONF_FILE_MAX);
|
||||
}
|
||||
if (vsf_sysutil_retval_is_error(retval))
|
||||
{
|
||||
die2("cannot read user list file:", tunable_userlist_file);
|
||||
@ -144,7 +148,7 @@ drop_all_privs(void)
|
||||
{
|
||||
struct mystr user_str = INIT_MYSTR;
|
||||
struct mystr dir_str = INIT_MYSTR;
|
||||
int option = VSF_SECUTIL_OPTION_CHROOT | VSF_SECUTIL_OPTION_NO_PROCS;
|
||||
unsigned int option = VSF_SECUTIL_OPTION_CHROOT | VSF_SECUTIL_OPTION_NO_PROCS;
|
||||
if (!tunable_ssl_enable)
|
||||
{
|
||||
/* Unfortunately, can only enable this if we can be sure of not using SSL.
|
||||
@ -152,8 +156,14 @@ drop_all_privs(void)
|
||||
*/
|
||||
option |= VSF_SECUTIL_OPTION_NO_FDS;
|
||||
}
|
||||
str_alloc_text(&user_str, tunable_nopriv_user);
|
||||
str_alloc_text(&dir_str, tunable_secure_chroot_dir);
|
||||
if (tunable_nopriv_user)
|
||||
{
|
||||
str_alloc_text(&user_str, tunable_nopriv_user);
|
||||
}
|
||||
if (tunable_secure_chroot_dir)
|
||||
{
|
||||
str_alloc_text(&dir_str, tunable_secure_chroot_dir);
|
||||
}
|
||||
/* Be kind: give good error message if the secure dir is missing */
|
||||
{
|
||||
struct vsf_sysutil_statbuf* p_statbuf = 0;
|
||||
@ -315,7 +325,11 @@ process_login_req(struct vsf_session* p_sess)
|
||||
return;
|
||||
break;
|
||||
case kVSFLoginAnon:
|
||||
str_alloc_text(&p_sess->user_str, tunable_ftp_username);
|
||||
str_free(&p_sess->user_str);
|
||||
if (tunable_ftp_username)
|
||||
{
|
||||
str_alloc_text(&p_sess->user_str, tunable_ftp_username);
|
||||
}
|
||||
common_do_login(p_sess, &p_sess->user_str, 1, 1);
|
||||
break;
|
||||
case kVSFLoginReal:
|
||||
@ -328,9 +342,12 @@ process_login_req(struct vsf_session* p_sess)
|
||||
if (tunable_chroot_list_enable)
|
||||
{
|
||||
struct mystr chroot_list_file = INIT_MYSTR;
|
||||
int retval = str_fileread(&chroot_list_file,
|
||||
tunable_chroot_list_file,
|
||||
VSFTP_CONF_FILE_MAX);
|
||||
int retval = -1;
|
||||
if (tunable_chroot_list_file)
|
||||
{
|
||||
retval = str_fileread(&chroot_list_file, tunable_chroot_list_file,
|
||||
VSFTP_CONF_FILE_MAX);
|
||||
}
|
||||
if (vsf_sysutil_retval_is_error(retval))
|
||||
{
|
||||
die2("could not read chroot() list file:",
|
||||
@ -413,7 +430,10 @@ common_do_login(struct vsf_session* p_sess, const struct mystr* p_user_str,
|
||||
{
|
||||
p_sess->is_guest = 1;
|
||||
/* Remap to the guest user */
|
||||
str_alloc_text(&guest_user_str, tunable_guest_username);
|
||||
if (tunable_guest_username)
|
||||
{
|
||||
str_alloc_text(&guest_user_str, tunable_guest_username);
|
||||
}
|
||||
p_user_str = &guest_user_str;
|
||||
if (!tunable_virtual_use_local_privs)
|
||||
{
|
||||
|
@ -26,7 +26,14 @@ die2(const char* p_text1, const char* p_text2)
|
||||
{
|
||||
struct mystr die_str = INIT_MYSTR;
|
||||
str_alloc_text(&die_str, p_text1);
|
||||
str_append_text(&die_str, p_text2);
|
||||
if (p_text2)
|
||||
{
|
||||
str_append_text(&die_str, p_text2);
|
||||
}
|
||||
else
|
||||
{
|
||||
str_append_text(&die_str, "(null)");
|
||||
}
|
||||
die(str_getbuf(&die_str));
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef VSF_VERSION_H
|
||||
#define VSF_VERSION_H
|
||||
|
||||
#define VSF_VERSION "3.0.0"
|
||||
#define VSF_VERSION "3.0.1"
|
||||
|
||||
#endif /* VSF_VERSION_H */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user