2 * Part of Very Secure FTPd
7 * Code for the "one process" security model. The one process security model
8 * is born for the purposes of raw speed at the expense of compromising the
9 * purity of the security model.
10 * The one process model will typically be disabled, for security reasons.
11 * Only sites with huge numbers of concurrent users are likely to feel the
12 * pain of two processes per session.
16 #include "postlogin.h"
24 #include "sysdeputil.h"
26 #include "ptracesandbox.h"
27 #include "ftppolicy.h"
28 #include "seccompsandbox.h"
30 static void one_process_start(void* p_arg
);
33 vsf_one_process_start(struct vsf_session
* p_sess
)
35 if (tunable_ptrace_sandbox
)
37 struct pt_sandbox
* p_sandbox
= ptrace_sandbox_alloc();
40 die("could not allocate sandbox (only works for 32-bit builds)");
42 policy_setup(p_sandbox
, p_sess
);
43 if (ptrace_sandbox_launch_process(p_sandbox
,
47 die("could not launch sandboxed child");
49 /* TODO - could drop privs here. For now, run as root as the attack surface
50 * is negligible, and running as root permits us to correctly deliver the
51 * parent death signal upon unexpected crash.
53 (void) ptrace_sandbox_run_processes(p_sandbox
);
54 ptrace_sandbox_free(p_sandbox
);
59 one_process_start((void*) p_sess
);
64 one_process_start(void* p_arg
)
66 struct vsf_session
* p_sess
= (struct vsf_session
*) p_arg
;
67 unsigned int caps
= 0;
68 if (tunable_chown_uploads
)
70 caps
|= kCapabilityCAP_CHOWN
;
72 if (tunable_connect_from_port_20
)
74 caps
|= kCapabilityCAP_NET_BIND_SERVICE
;
77 struct mystr user_name
= INIT_MYSTR
;
78 struct mystr chdir_str
= INIT_MYSTR
;
79 if (tunable_ftp_username
)
81 str_alloc_text(&user_name
, tunable_ftp_username
);
83 if (tunable_anon_root
)
85 str_alloc_text(&chdir_str
, tunable_anon_root
);
87 if (tunable_run_as_launching_user
)
89 if (!str_isempty(&chdir_str
))
91 str_chdir(&chdir_str
);
96 vsf_secutil_change_credentials(&user_name
, 0, &chdir_str
, caps
,
97 VSF_SECUTIL_OPTION_CHROOT
|
98 VSF_SECUTIL_OPTION_USE_GROUPS
|
99 VSF_SECUTIL_OPTION_NO_PROCS
);
101 str_free(&user_name
);
102 str_free(&chdir_str
);
104 if (tunable_ptrace_sandbox
)
106 ptrace_sandbox_attach_point();
108 seccomp_sandbox_init();
109 seccomp_sandbox_setup_postlogin(p_sess
);
110 seccomp_sandbox_lockdown();
111 init_connection(p_sess
);
115 vsf_one_process_login(struct vsf_session
* p_sess
,
116 const struct mystr
* p_pass_str
)
118 enum EVSFPrivopLoginResult login_result
=
119 vsf_privop_do_login(p_sess
, p_pass_str
);
120 switch (login_result
)
126 p_sess
->is_anonymous
= 1;
127 process_post_login(p_sess
);
134 bug("bad state in vsf_one_process_login");
140 vsf_one_process_get_priv_data_sock(struct vsf_session
* p_sess
)
142 unsigned short port
= vsf_sysutil_sockaddr_get_port(p_sess
->p_port_sockaddr
);
143 return vsf_privop_get_ftp_port_sock(p_sess
, port
, 1);
147 vsf_one_process_pasv_cleanup(struct vsf_session
* p_sess
)
149 vsf_privop_pasv_cleanup(p_sess
);
153 vsf_one_process_pasv_active(struct vsf_session
* p_sess
)
155 return vsf_privop_pasv_active(p_sess
);
159 vsf_one_process_listen(struct vsf_session
* p_sess
)
161 return vsf_privop_pasv_listen(p_sess
);
165 vsf_one_process_get_pasv_fd(struct vsf_session
* p_sess
)
167 return vsf_privop_accept_pasv(p_sess
);
171 vsf_one_process_chown_upload(struct vsf_session
* p_sess
, int fd
)
173 vsf_privop_do_file_chown(p_sess
, fd
);