コード例 #1
0
ファイル: session.c プロジェクト: yiyi99/Tinyftp
void begin_session(session_t *sess)
{
    /*开启接收带外数据*/
    activate_oobinline(sess->ctrl_fd);

    /*
    	int sockfds[2];
    	if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds) < 0)
    	{
    		ERR_EXIT("socketpair");
    	}
    */
    /*初始化内部进程间通讯通道*/
    priv_sock_init(sess);

    pid_t pid;
    pid = fork();
    if (pid < 0)
    {
        ERR_EXIT("fork");
    }

    if (pid == 0)
    {
        //ftp服务进程
        /*
        close(sockfds[0]);
        sess->child_fd = sockfds[1];
        */
        /*设置子进程环境*/
        priv_sock_set_child_context(sess);
        handle_child(sess);
    }
    else
    {
        //nobody进程
        /*
        close(sockfds[1]);
        sess->parent_fd = sockfds[0];
        */
        /*设置父进程环境*/
        priv_sock_set_parent_context(sess);
        handle_parent(sess);
    }
}
コード例 #2
0
ファイル: session.cpp プロジェクト: chenhongjun/2016first
void begin_session(session_t* psess)
{
	
	priv_sock_init(psess);

	pid_t pid = fork();
	if (pid == -1)
		ERR_EXIT("fork");
	if (pid == 0)
	{//服务进程
		priv_sock_set_child_context(psess);
		handle_child(psess);
	}
	else if(pid > 0)
	{//nobody进程
		priv_sock_set_parent_context(psess);
		handle_parent(psess);
	}
}
コード例 #3
0
ファイル: session.c プロジェクト: xsun89/miniftp
void begin_session(session_t *sess)
{
    activate_oobinline(sess->ctrl_fd);
    priv_sock_init(sess);
    pid_t pid;
    pid = fork();
    if(pid < 0)
        ERR_EXIT("fork");

    if(pid == 0)
    {
        /* ftp process */
        priv_sock_set_child_context(sess);
        handle_child(sess);
    }else
    {
        /* nobody process */
        priv_sock_set_parent_context(sess);
        handle_parent(sess);
    }
}
コード例 #4
0
ファイル: session.c プロジェクト: zhangxiao696/ftp-xiao2016
void begin_session(session_t *sess)
{
/*	struct passwd *pw = getpwnam("nobody");
	if(pw == NULL)
		return;

	if(setegid(pw->pw_gid) < 0)
		ERR_EXIT("setegid");
	if(seteuid(pw->pw_uid) < 0)
		ERR_EXIT("seteuid");*/

	int sockfds[2];
	if(socketpair(PF_UNIX, SOCK_STREAM, 0, sockfds) < 0)
		ERR_EXIT("sockpair");

    priv_sock_init(sess);

	pid_t pid;
	pid = fork();

	if(pid < 0)
		ERR_EXIT("fork");

	if (pid == 0)
	{
/*		close(sockfds[0]);
		sess->parent_fd = sockfds[1];*/

        priv_sock_set_child_context(sess);
		handle_child(sess);
	}
	else
	{
/*		close(sockfds[1]);
		sess->child_fd = sockfds[0];*/

        priv_sock_set_parent_context(sess);
		handle_parent(sess);
	}
}
コード例 #5
0
void
vsf_two_process_start(struct vsf_session* p_sess)
{
  vsf_sysutil_install_sighandler(kVSFSysUtilSigTERM, handle_sigterm, 0, 1);
  /* Overrides the SIGKILL setting set by the standalone listener. */
  vsf_set_term_if_parent_dies();
  /* Create the comms channel between privileged parent and no-priv child */
  priv_sock_init(p_sess);
  if (tunable_ssl_enable)
  {
    /* Create the comms channel between the no-priv SSL child and the low-priv
     * protocol handling child.
     */
    ssl_comm_channel_init(p_sess);
  }
  vsf_sysutil_install_sighandler(kVSFSysUtilSigCHLD, handle_sigchld, 0, 1);
  {
    int newpid;
    if (tunable_isolate_network)
    {
      newpid = vsf_sysutil_fork_newnet();
    }
    else
    {
      newpid = vsf_sysutil_fork();
    }
    if (newpid != 0)
    {
      priv_sock_set_parent_context(p_sess);
      if (tunable_ssl_enable)
      {
        ssl_comm_channel_set_consumer_context(p_sess);
      }
      /* Parent - go into pre-login parent process mode */
      while (1)
      {
        process_login_req(p_sess);
      }
    }
  }
  /* Child process - time to lose as much privilege as possible and do the
   * login processing
   */
  vsf_set_die_if_parent_dies();
  priv_sock_set_child_context(p_sess);
  if (tunable_ssl_enable)
  {
    ssl_comm_channel_set_producer_context(p_sess);
  }
  if (tunable_local_enable && tunable_userlist_enable)
  {
    int 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);
    }
  }
  drop_all_privs();
  init_connection(p_sess);
  /* NOTREACHED */
}
コード例 #6
0
static void
common_do_login(struct vsf_session* p_sess, const struct mystr* p_user_str,
                int do_chroot, int anon)
{
  int was_anon = anon;
  const struct mystr* p_orig_user_str = p_user_str;
  int newpid;
  vsf_sysutil_install_null_sighandler(kVSFSysUtilSigCHLD);
  /* Tells the pre-login child all is OK (it may exit in response) */
  priv_sock_send_result(p_sess->parent_fd, PRIV_SOCK_RESULT_OK);
  if (!p_sess->control_use_ssl)
  {
    (void) vsf_sysutil_wait();
  }
  else
  {
    p_sess->ssl_slave_active = 1;
  }
  /* Handle loading per-user config options */
  handle_per_user_config(p_user_str);
  /* Set this before we fork */
  p_sess->is_anonymous = anon;
  priv_sock_close(p_sess);
  priv_sock_init(p_sess);
  vsf_sysutil_install_sighandler(kVSFSysUtilSigCHLD, handle_sigchld, 0, 1);
  if (tunable_isolate_network && !tunable_port_promiscuous)
  {
    newpid = vsf_sysutil_fork_newnet();
  }
  else
  {
    newpid = vsf_sysutil_fork();
  }
  if (newpid == 0)
  {
    struct mystr guest_user_str = INIT_MYSTR;
    struct mystr chroot_str = INIT_MYSTR;
    struct mystr chdir_str = INIT_MYSTR;
    struct mystr userdir_str = INIT_MYSTR;
    unsigned int secutil_option = VSF_SECUTIL_OPTION_USE_GROUPS |
                                  VSF_SECUTIL_OPTION_NO_PROCS;
    /* Child - drop privs and start proper FTP! */
    /* This PR_SET_PDEATHSIG doesn't work for all possible process tree setups.
     * The other cases are taken care of by a shutdown() of the command
     * connection in our SIGTERM handler.
     */
    vsf_set_die_if_parent_dies();
    priv_sock_set_child_context(p_sess);
    if (tunable_guest_enable && !anon)
    {
      p_sess->is_guest = 1;
      /* Remap to the guest user */
      str_alloc_text(&guest_user_str, tunable_guest_username);
      p_user_str = &guest_user_str;
      if (!tunable_virtual_use_local_privs)
      {
        anon = 1;
        do_chroot = 1;
      }
    }
    if (do_chroot)
    {
      secutil_option |= VSF_SECUTIL_OPTION_CHROOT;
    }
    if (!anon)
    {
      secutil_option |= VSF_SECUTIL_OPTION_CHANGE_EUID;
    }
    calculate_chdir_dir(was_anon, &userdir_str, &chroot_str, &chdir_str,
                        p_user_str, p_orig_user_str);
    vsf_secutil_change_credentials(p_user_str, &userdir_str, &chroot_str,
                                   0, secutil_option);
    if (!str_isempty(&chdir_str))
    {
      (void) str_chdir(&chdir_str);
    }
    str_free(&guest_user_str);
    str_free(&chroot_str);
    str_free(&chdir_str);
    str_free(&userdir_str);
    p_sess->is_anonymous = anon;
    process_post_login(p_sess);
    bug("should not get here: common_do_login");
  }
  /* Parent */
  priv_sock_set_parent_context(p_sess);
  if (tunable_ssl_enable)
  {
    ssl_comm_channel_set_producer_context(p_sess);
  }
  vsf_priv_parent_postlogin(p_sess);
  bug("should not get here in common_do_login");
}
コード例 #7
0
ファイル: sslslave.c プロジェクト: AllardJ/Tomato
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");
    }
  }
}