⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftppolicy.c

📁 文件传输协议linux 下vsftpd2.1.0.tar.gz
💻 C
字号:
/* * Part of Very Secure FTPd * Licence: GPL v2 * Author: Chris Evans * ftppolicy.c * * Code to build a sandbox policy based on current session options. */#include "ftppolicy.h"#include "ptracesandbox.h"#include "tunables.h"#include "session.h"#include "sysutil.h"/* For AF_INET etc. network constants. */#include <sys/types.h>#include <sys/socket.h>#include <netinet/in_systm.h>#include <netinet/in.h>#include <netinet/ip.h>#include <netinet/tcp.h>static int socket_validator(struct pt_sandbox* p_sandbox, void* p_arg);static int connect_validator(struct pt_sandbox* p_sandbox, void* p_arg);static int getsockopt_validator(struct pt_sandbox* p_sandbox, void* p_arg);static int setsockopt_validator(struct pt_sandbox* p_sandbox, void* p_arg);voidpolicy_setup(struct pt_sandbox* p_sandbox, const struct vsf_session* p_sess){  int is_anon = p_sess->is_anonymous;  /* Always need to be able to exit! */  ptrace_sandbox_permit_exit(p_sandbox);  /* Needed for memory management. */  ptrace_sandbox_permit_mmap(p_sandbox);  ptrace_sandbox_permit_mprotect(p_sandbox);  ptrace_sandbox_permit_brk(p_sandbox);  /* Simple reads and writes are required. Permitting write does not imply   * filesystem write access because access control is done at open time.   */  ptrace_sandbox_permit_read(p_sandbox);  ptrace_sandbox_permit_write(p_sandbox);  /* Querying time is harmless; used for log timestamps and internally to   * OpenSSL   */  ptrace_sandbox_permit_query_time(p_sandbox);  /* Stat'ing is needed for downloading and directory listings. Can blanket   * enable for any filename thanks to the chroot().   */  ptrace_sandbox_permit_file_stats(p_sandbox);  ptrace_sandbox_permit_fd_stats(p_sandbox);  /* Querying and changing directory. */  ptrace_sandbox_permit_getcwd(p_sandbox);  ptrace_sandbox_permit_chdir(p_sandbox);  /* Setting umask. */  ptrace_sandbox_permit_umask(p_sandbox);  /* Since we're in a chroot(), we can just blanket allow filesystem readonly   * open.   */  ptrace_sandbox_permit_open(p_sandbox, 0);  ptrace_sandbox_permit_close(p_sandbox);  /* High-speed transfers... */  ptrace_sandbox_permit_sendfile(p_sandbox);  /* Reading directories. */  ptrace_sandbox_permit_getdents(p_sandbox);  /* Reading symlink targets. */  ptrace_sandbox_permit_readlink(p_sandbox);  /* File locking. */  ptrace_sandbox_permit_fcntl(p_sandbox);  /* Seeking for REST. */  ptrace_sandbox_permit_seek(p_sandbox);  /* Select for data connection readyness. */  ptrace_sandbox_permit_select(p_sandbox);  /* Always need ability to take signals (SIGPIPE) */  ptrace_sandbox_permit_sigreturn(p_sandbox);  /* Sleeping (bandwidth limit, connect retires, anon login fails) */  ptrace_sandbox_permit_sleep(p_sandbox);  /* May need ability to install signal handlers. */  if (tunable_async_abor_enable ||      tunable_idle_session_timeout > 0 ||      tunable_data_connection_timeout > 0)  {    ptrace_sandbox_permit_sigaction(p_sandbox);  }  /* May need ability to set up timeout alarms. */  if (tunable_idle_session_timeout > 0 || tunable_data_connection_timeout > 0)  {    ptrace_sandbox_permit_alarm(p_sandbox);  }  /* TODO - Grrrr! nscd cache access is leaking into child. Need to find out   * out how to disable that. Also means that text_userdb_names loads values   * from the real system data.   */  if (tunable_text_userdb_names)  {    ptrace_sandbox_permit_mremap(p_sandbox);  }  /* Set up network permissions according to config and session. */  ptrace_sandbox_permit_recv(p_sandbox);  ptrace_sandbox_permit_shutdown(p_sandbox);  ptrace_sandbox_permit_socket(p_sandbox);  ptrace_sandbox_set_socket_validator(p_sandbox,                                      socket_validator,                                      (void*) p_sess);  ptrace_sandbox_permit_bind(p_sandbox);  /* Yes, reuse of the connect validator is intentional. */  ptrace_sandbox_set_bind_validator(p_sandbox,                                    connect_validator,                                    (void*) p_sess);  ptrace_sandbox_permit_setsockopt(p_sandbox);  ptrace_sandbox_set_setsockopt_validator(p_sandbox, setsockopt_validator, 0);  ptrace_sandbox_permit_shutdown(p_sandbox);  if (tunable_port_enable)  {    ptrace_sandbox_permit_connect(p_sandbox);    ptrace_sandbox_set_connect_validator(p_sandbox,                                         connect_validator,                                         (void*) p_sess);    ptrace_sandbox_permit_getsockopt(p_sandbox);    ptrace_sandbox_set_getsockopt_validator(p_sandbox, getsockopt_validator, 0);  }  if (tunable_pasv_enable)  {    ptrace_sandbox_permit_listen(p_sandbox);    ptrace_sandbox_permit_accept(p_sandbox);  }  /* Set up write permissions according to config and session. */  if (tunable_write_enable)  {    if (!is_anon || tunable_anon_upload_enable)    {      ptrace_sandbox_permit_open(p_sandbox, 1);    }    if (!is_anon || tunable_anon_mkdir_write_enable)    {      ptrace_sandbox_permit_mkdir(p_sandbox);    }    if (!is_anon || tunable_anon_other_write_enable)    {      ptrace_sandbox_permit_unlink(p_sandbox);      ptrace_sandbox_permit_rmdir(p_sandbox);      ptrace_sandbox_permit_rename(p_sandbox);      ptrace_sandbox_permit_ftruncate(p_sandbox);      if (tunable_mdtm_write)      {        ptrace_sandbox_permit_utime(p_sandbox);      }    }    if (!is_anon && tunable_chmod_enable)    {      ptrace_sandbox_permit_chmod(p_sandbox);    }    if (is_anon && tunable_chown_uploads)    {      ptrace_sandbox_permit_fchmod(p_sandbox);      ptrace_sandbox_permit_fchown(p_sandbox);    }  }}static intsocket_validator(struct pt_sandbox* p_sandbox, void* p_arg){  struct vsf_session* p_sess = (struct vsf_session*) p_arg;  unsigned long arg1;  unsigned long arg2;  unsigned long expected_family = AF_INET;  if (vsf_sysutil_sockaddr_is_ipv6(p_sess->p_local_addr))  {    expected_family = AF_INET6;  }  int ret = ptrace_sandbox_get_socketcall_arg(p_sandbox, 0, &arg1);  if (ret != 0)  {    return ret;  }  ret = ptrace_sandbox_get_socketcall_arg(p_sandbox, 1, &arg2);  if (ret != 0)  {    return ret;  }  if (arg1 != expected_family || arg2 != SOCK_STREAM)  {    return -1;  }  return 0;}static intconnect_validator(struct pt_sandbox* p_sandbox, void* p_arg){  struct vsf_session* p_sess = (struct vsf_session*) p_arg;  unsigned long arg2;  unsigned long arg3;  unsigned long expected_family = AF_INET;  unsigned long expected_len = sizeof(struct sockaddr_in);  void* p_buf = 0;  struct sockaddr* p_sockaddr;  static struct vsf_sysutil_sockaddr* p_sockptr;  if (vsf_sysutil_sockaddr_is_ipv6(p_sess->p_local_addr))  {    expected_family = AF_INET6;    expected_len = sizeof(struct sockaddr_in6);  }  int ret = ptrace_sandbox_get_socketcall_arg(p_sandbox, 1, &arg2);  if (ret != 0)  {    return ret;  }  ret = ptrace_sandbox_get_socketcall_arg(p_sandbox, 2, &arg3);  if (ret != 0)  {    return ret;  }  if (arg3 != expected_len)  {    return -1;  }  p_buf = vsf_sysutil_malloc((int) expected_len);  ret = ptrace_sandbox_get_buf(p_sandbox, arg2, expected_len, p_buf);  if (ret != 0)  {    vsf_sysutil_free(p_buf);    return -2;  }  p_sockaddr = (struct sockaddr*) p_buf;  if (p_sockaddr->sa_family != expected_family)  {    vsf_sysutil_free(p_buf);    return -3;  }  if (expected_family == AF_INET)  {    struct sockaddr_in* p_sockaddr_in = (struct sockaddr_in*) p_sockaddr;    vsf_sysutil_sockaddr_alloc_ipv4(&p_sockptr);    vsf_sysutil_sockaddr_set_ipv4addr(p_sockptr,                                      (const unsigned char*)                                          &p_sockaddr_in->sin_addr);  }  else  {    struct sockaddr_in6* p_sockaddr_in6 = (struct sockaddr_in6*) p_sockaddr;    vsf_sysutil_sockaddr_alloc_ipv6(&p_sockptr);    vsf_sysutil_sockaddr_set_ipv6addr(p_sockptr,                                      (const unsigned char*)                                          &p_sockaddr_in6->sin6_addr);  }  if (!vsf_sysutil_sockaddr_addr_equal(p_sess->p_remote_addr, p_sockptr))  {    vsf_sysutil_free(p_buf);    return -4;  }  vsf_sysutil_free(p_buf);  return 0;}static intgetsockopt_validator(struct pt_sandbox* p_sandbox, void* p_arg){  unsigned long arg2;  unsigned long arg3;  (void) p_arg;  int ret = ptrace_sandbox_get_socketcall_arg(p_sandbox, 1, &arg2);  if (ret != 0)  {    return ret;  }  ret = ptrace_sandbox_get_socketcall_arg(p_sandbox, 2, &arg3);  if (ret != 0)  {    return ret;  }  if (arg2 != SOL_SOCKET || arg3 != SO_ERROR)  {    return -1;  }  return 0;}static intsetsockopt_validator(struct pt_sandbox* p_sandbox, void* p_arg){  unsigned long arg2;  unsigned long arg3;  (void) p_arg;  int ret = ptrace_sandbox_get_socketcall_arg(p_sandbox, 1, &arg2);  if (ret != 0)  {    return ret;  }  ret = ptrace_sandbox_get_socketcall_arg(p_sandbox, 2, &arg3);  if (ret != 0)  {    return ret;  }  if (arg2 == SOL_SOCKET)  {    if (arg3 != SO_KEEPALIVE &&        arg3 != SO_REUSEADDR &&        arg3 != SO_OOBINLINE &&        arg3 != SO_LINGER)    {      return -1;    }  }  else if (arg2 == IPPROTO_TCP)  {    if (arg3 != TCP_NODELAY)    {      return -2;    }  }  else if (arg2 == IPPROTO_IP)  {    if (arg3 != IP_TOS)    {      return -3;    }  }  else  {    return -4;  }  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -