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"
29 static void one_process_start(void* p_arg
);
32 vsf_one_process_start(struct vsf_session
* p_sess
)
36 struct pt_sandbox
* p_sandbox
= ptrace_sandbox_alloc();
39 die("could not allocate sandbox (only works for 32-bit builds)");
41 policy_setup(p_sandbox
, p_sess
);
42 if (ptrace_sandbox_launch_process(p_sandbox
,
46 die("could not launch sandboxed child");
48 /* TODO - could drop privs here. For now, run as root as the attack surface
49 * is negligible, and running as root permits us to correctly deliver the
50 * parent death signal upon unexpected crash.
52 (void) ptrace_sandbox_run_processes(p_sandbox
);
53 ptrace_sandbox_free(p_sandbox
);
58 one_process_start((void*) p_sess
);
63 one_process_start(void* p_arg
)
65 struct vsf_session
* p_sess
= (struct vsf_session
*) p_arg
;
66 unsigned int caps
= 0;
67 if (tunable_chown_uploads
)
69 caps
|= kCapabilityCAP_CHOWN
;
71 if (tunable_connect_from_port_20
)
73 caps
|= kCapabilityCAP_NET_BIND_SERVICE
;
76 struct mystr user_name
= INIT_MYSTR
;
77 struct mystr chdir_str
= INIT_MYSTR
;
78 str_alloc_text(&user_name
, tunable_ftp_username
);
79 if (tunable_anon_root
)
81 str_alloc_text(&chdir_str
, tunable_anon_root
);
83 if (tunable_run_as_launching_user
)
85 if (!str_isempty(&chdir_str
))
87 str_chdir(&chdir_str
);
92 vsf_secutil_change_credentials(&user_name
, 0, &chdir_str
, caps
,
93 VSF_SECUTIL_OPTION_CHROOT
|
94 VSF_SECUTIL_OPTION_USE_GROUPS
|
95 VSF_SECUTIL_OPTION_NO_PROCS
);
102 ptrace_sandbox_attach_point();
104 init_connection(p_sess
);
108 vsf_one_process_login(struct vsf_session
* p_sess
,
109 const struct mystr
* p_pass_str
)
111 enum EVSFPrivopLoginResult login_result
=
112 vsf_privop_do_login(p_sess
, p_pass_str
);
113 switch (login_result
)
119 p_sess
->is_anonymous
= 1;
120 process_post_login(p_sess
);
123 bug("bad state in vsf_one_process_login");
129 vsf_one_process_get_priv_data_sock(struct vsf_session
* p_sess
)
131 unsigned short port
= vsf_sysutil_sockaddr_get_port(p_sess
->p_port_sockaddr
);
132 return vsf_privop_get_ftp_port_sock(p_sess
, port
, 1);
136 vsf_one_process_pasv_cleanup(struct vsf_session
* p_sess
)
138 vsf_privop_pasv_cleanup(p_sess
);
142 vsf_one_process_pasv_active(struct vsf_session
* p_sess
)
144 return vsf_privop_pasv_active(p_sess
);
148 vsf_one_process_listen(struct vsf_session
* p_sess
)
150 return vsf_privop_pasv_listen(p_sess
);
154 vsf_one_process_get_pasv_fd(struct vsf_session
* p_sess
)
156 return vsf_privop_accept_pasv(p_sess
);
160 vsf_one_process_chown_upload(struct vsf_session
* p_sess
, int fd
)
162 vsf_privop_do_file_chown(p_sess
, fd
);