void handle_parent(session_t *sess) { minimize_privilege(); //使nobody用户进程的权限最小,仅仅获得绑定特权端口的权限 char cmd; while (1) { cmd = priv_sock_get_cmd(sess->parent_fd); // 解析内部命令 // 处理内部命令 switch (cmd) { case PRIV_SOCK_GET_DATA_SOCK: privop_pasv_get_data_sock(sess); break; case PRIV_SOCK_PASV_ACTIVE: privop_pasv_active(sess); break; case PRIV_SOCK_PASV_LISTEN: privop_pasv_listen(sess); break; case PRIV_SOCK_PASV_ACCEPT: privop_pasv_accept(sess); break; } } }
void handle_nobody(session_t* sess) { minimize_privilege(); char cmd; while (1) { // 获取ftp协议进程传递的消息 cmd = priv_sock_get_cmd(sess->nobody_fd); switch (cmd) { case PRIV_SOCK_GET_DATA_SOCK: privop_port_get_data_sock(sess); break; case PRIV_SOCK_PASV_ACTIVE: privop_pasv_active(sess); break; case PRIV_SOCK_PASV_LISTEN: privop_pasv_listen(sess); break; case PRIV_SOCK_PASV_ACCEPT: privop_pasv_accept(sess); break; } } }
void PrivPar::handle_parent(session_t *sess) { minimize_privace(); char cmd; while (1) { cmd = priv_sock_get_cmd(sess->parent_fd); // 处理内部命令 switch (cmd) { case PRIV_SOCK_GET_DATA_SOCK: privop_pasv_get_data_sock(sess); break; case PRIV_SOCK_PASV_ACTIVE: privop_pasv_active(sess); break; case PRIV_SOCK_PASV_LISTEN: privop_pasv_listen(sess); break; case PRIV_SOCK_PASV_ACCEPT: privop_pasv_accept(sess); break; } } }
static void process_post_login_req(struct vsf_session* p_sess) { /* Blocks */ char cmd = priv_sock_get_cmd(p_sess); if (tunable_chown_uploads && cmd == PRIV_SOCK_CHOWN) { cmd_process_chown(p_sess); } else if (tunable_connect_from_port_20 && cmd == PRIV_SOCK_GET_DATA_SOCK) { cmd_process_get_data_sock(p_sess); } else { die("bad post login request"); } }
static void process_post_login_req(struct vsf_session* p_sess) { char cmd; vsf_sysutil_unblock_sig(kVSFSysUtilSigCHLD); /* Blocks */ cmd = priv_sock_get_cmd(p_sess->parent_fd); vsf_sysutil_block_sig(kVSFSysUtilSigCHLD); if (tunable_chown_uploads && cmd == PRIV_SOCK_CHOWN) { cmd_process_chown(p_sess); } else if (tunable_connect_from_port_20 && cmd == PRIV_SOCK_GET_DATA_SOCK) { cmd_process_get_data_sock(p_sess); } else { die("bad request in process_post_login_req"); } }
static void process_ssl_slave_req(struct vsf_session* p_sess) { while (1) { char cmd = priv_sock_get_cmd(p_sess->ssl_slave_fd); int retval; if (cmd == PRIV_SOCK_GET_USER_CMD) { ftp_getline(p_sess, &p_sess->ftp_cmd_str, p_sess->p_control_line_buf); priv_sock_send_str(p_sess->ssl_slave_fd, &p_sess->ftp_cmd_str); } else if (cmd == PRIV_SOCK_WRITE_USER_RESP) { priv_sock_get_str(p_sess->ssl_slave_fd, &p_sess->ftp_cmd_str); retval = ftp_write_str(p_sess, &p_sess->ftp_cmd_str, kVSFRWControl); priv_sock_send_int(p_sess->ssl_slave_fd, retval); } else { die("bad request in process_ssl_slave_req"); } } }
static void process_login_req(struct vsf_session* p_sess) { enum EVSFPrivopLoginResult e_login_result = kVSFLoginNull; /* Blocks */ if (priv_sock_get_cmd(p_sess) != PRIV_SOCK_LOGIN) { die("bad request"); } /* Get username and password - we must distrust these */ { struct mystr password_str = INIT_MYSTR; priv_sock_get_str(p_sess, &p_sess->user_str); priv_sock_get_str(p_sess, &password_str); e_login_result = vsf_privop_do_login(p_sess, &password_str); str_free(&password_str); } switch (e_login_result) { case kVSFLoginFail: priv_sock_send_result(p_sess, PRIV_SOCK_RESULT_BAD); return; break; case kVSFLoginAnon: str_alloc_text(&p_sess->user_str, tunable_ftp_username); common_do_login(p_sess, &p_sess->user_str, 1, 1); break; case kVSFLoginReal: { int do_chroot = 0; if (tunable_chroot_local_user) { do_chroot = 1; } 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); if (vsf_sysutil_retval_is_error(retval)) { die("cannot open chroot() user list file"); } if (str_contains_line(&chroot_list_file, &p_sess->user_str)) { if (do_chroot) { do_chroot = 0; } else { do_chroot = 1; } } str_free(&chroot_list_file); } common_do_login(p_sess, &p_sess->user_str, do_chroot, 0); } break; default: bug("weird state in process_login_request"); break; } /* NOTREACHED */ }
void ssl_slave(struct vsf_session* p_sess) { struct mystr data_str = INIT_MYSTR; str_reserve(&data_str, VSFTP_DATA_BUFSIZE); /* Before becoming the slave, clear the alarm for the FTP protocol. */ vsf_sysutil_clear_alarm(); /* No need for any further communications with the privileged parent. */ priv_sock_set_parent_context(p_sess); if (tunable_setproctitle_enable) { vsf_sysutil_setproctitle("SSL handler"); } while (1) { char cmd = priv_sock_get_cmd(p_sess->ssl_slave_fd); int ret; if (cmd == PRIV_SOCK_GET_USER_CMD) { ret = ftp_getline(p_sess, &p_sess->ftp_cmd_str, p_sess->p_control_line_buf); priv_sock_send_int(p_sess->ssl_slave_fd, ret); if (ret >= 0) { priv_sock_send_str(p_sess->ssl_slave_fd, &p_sess->ftp_cmd_str); } } else if (cmd == PRIV_SOCK_WRITE_USER_RESP) { priv_sock_get_str(p_sess->ssl_slave_fd, &p_sess->ftp_cmd_str); ret = ftp_write_str(p_sess, &p_sess->ftp_cmd_str, kVSFRWControl); priv_sock_send_int(p_sess->ssl_slave_fd, ret); } else if (cmd == PRIV_SOCK_DO_SSL_HANDSHAKE) { char result = PRIV_SOCK_RESULT_BAD; if (p_sess->data_fd != -1 || p_sess->p_data_ssl != 0) { bug("state not clean"); } p_sess->data_fd = priv_sock_recv_fd(p_sess->ssl_slave_fd); ret = ssl_accept(p_sess, p_sess->data_fd); if (ret == 1) { result = PRIV_SOCK_RESULT_OK; } else { vsf_sysutil_close(p_sess->data_fd); p_sess->data_fd = -1; } priv_sock_send_result(p_sess->ssl_slave_fd, result); } else if (cmd == PRIV_SOCK_DO_SSL_READ) { str_trunc(&data_str, VSFTP_DATA_BUFSIZE); ret = ssl_read_into_str(p_sess, p_sess->p_data_ssl, &data_str); priv_sock_send_int(p_sess->ssl_slave_fd, ret); priv_sock_send_str(p_sess->ssl_slave_fd, &data_str); } else if (cmd == PRIV_SOCK_DO_SSL_WRITE) { priv_sock_get_str(p_sess->ssl_slave_fd, &data_str); ret = ssl_write(p_sess->p_data_ssl, str_getbuf(&data_str), str_getlen(&data_str)); priv_sock_send_int(p_sess->ssl_slave_fd, ret); } else if (cmd == PRIV_SOCK_DO_SSL_CLOSE) { char result = PRIV_SOCK_RESULT_BAD; if (p_sess->data_fd == -1 && p_sess->p_data_ssl == 0) { result = PRIV_SOCK_RESULT_OK; } else { ret = ssl_data_close(p_sess); if (ret == 1) { result = PRIV_SOCK_RESULT_OK; } vsf_sysutil_close(p_sess->data_fd); p_sess->data_fd = -1; } priv_sock_send_result(p_sess->ssl_slave_fd, result); } else { die("bad request in process_ssl_slave_req"); } } }
//static Kitsune void process_login_req(struct vsf_session* p_sess) { enum EVSFPrivopLoginResult e_login_result = kVSFLoginNull; char cmd; if (!kitsune_is_updating()) { /* Kitsune */ vsf_sysutil_unblock_sig(kVSFSysUtilSigCHLD); /* Blocks */ cmd = priv_sock_get_cmd(p_sess->parent_fd); vsf_sysutil_block_sig(kVSFSysUtilSigCHLD); if (cmd != PRIV_SOCK_LOGIN) { die("bad request"); } } /* Kitsune, update point */ kitsune_update("twoprocess.c"); /* Kitsune, allow updating from blocking loop */ vsf_sysutil_kitsune_set_update_point("twoprocess.c"); /* Get username and password - we must distrust these */ { struct mystr password_str = INIT_MYSTR; priv_sock_get_str(p_sess->parent_fd, &p_sess->user_str); priv_sock_get_str(p_sess->parent_fd, &password_str); p_sess->control_use_ssl = priv_sock_get_int(p_sess->parent_fd); p_sess->data_use_ssl = priv_sock_get_int(p_sess->parent_fd); if (!tunable_ssl_enable) { p_sess->control_use_ssl = 0; p_sess->data_use_ssl = 0; } e_login_result = vsf_privop_do_login(p_sess, &password_str); str_free(&password_str); } switch (e_login_result) { case kVSFLoginFail: priv_sock_send_result(p_sess->parent_fd, PRIV_SOCK_RESULT_BAD); return; break; case kVSFLoginAnon: str_alloc_text(&p_sess->user_str, tunable_ftp_username); common_do_login(p_sess, &p_sess->user_str, 1, 1); break; case kVSFLoginReal: { int do_chroot = 0; if (tunable_chroot_local_user) { do_chroot = 1; } 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); if (vsf_sysutil_retval_is_error(retval)) { die2("could not open chroot() list file:", tunable_chroot_list_file); } if (str_contains_line(&chroot_list_file, &p_sess->user_str)) { if (do_chroot) { do_chroot = 0; } else { do_chroot = 1; } } str_free(&chroot_list_file); } common_do_login(p_sess, &p_sess->user_str, do_chroot, 0); } break; default: bug("weird state in process_login_request"); break; } /* NOTREACHED */ }