void
vsf_two_process_login(struct vsf_session* p_sess,
                      const struct mystr* p_pass_str)
{
  char result;
  priv_sock_send_cmd(p_sess, PRIV_SOCK_LOGIN);
  priv_sock_send_str(p_sess, &p_sess->user_str);
  priv_sock_send_str(p_sess, p_pass_str);
  result = priv_sock_get_result(p_sess);
  if (result == PRIV_SOCK_RESULT_OK)
  {
    /* Miracle. We don't emit the success message here. That is left to
     * process_post_login().
     * Exit normally, parent will wait for this and launch new child
     */
    vsf_sysutil_exit(0);
  }
  else if (result == PRIV_SOCK_RESULT_BAD)
  {
    /* Continue the processing loop.. */
    return;
  }
  else
  {
    die("priv_sock_get_result");
  }
}
int
ftp_write_str(const struct vsf_session* p_sess, const struct mystr* p_str,
              enum EVSFRWTarget target)
{
  if (target == kVSFRWData)
  {
    if (p_sess->data_use_ssl)
    {
      return ssl_write_str(p_sess->p_data_ssl, p_str);
    }
    else
    {
      return str_netfd_write(p_str, p_sess->data_fd);
    }
  }
  else
  {
    if (p_sess->control_use_ssl && p_sess->ssl_slave_active)
    {
      priv_sock_send_cmd(p_sess->ssl_consumer_fd, PRIV_SOCK_WRITE_USER_RESP);
      priv_sock_send_str(p_sess->ssl_consumer_fd, p_str);
      return priv_sock_get_int(p_sess->ssl_consumer_fd);
    }
    else if (p_sess->control_use_ssl)
    {
      return ssl_write_str(p_sess->p_control_ssl, p_str);
    }
    else
    {
      return str_netfd_write(p_str, VSFTP_COMMAND_FD);
    }
  }
}
void
vsf_two_process_login(struct vsf_session* p_sess,
                      const struct mystr* p_pass_str)
{
  char result;
  priv_sock_send_cmd(p_sess->child_fd, PRIV_SOCK_LOGIN);
  priv_sock_send_str(p_sess->child_fd, &p_sess->user_str);
  priv_sock_send_str(p_sess->child_fd, p_pass_str);
  priv_sock_send_int(p_sess->child_fd, p_sess->control_use_ssl);
  priv_sock_send_int(p_sess->child_fd, p_sess->data_use_ssl);
  result = priv_sock_get_result(p_sess->child_fd);
  if (result == PRIV_SOCK_RESULT_OK)
  {
    /* Miracle. We don't emit the success message here. That is left to
     * process_post_login().
     * Exit normally, unless we are remaining as the SSL read / write child.
     */
    if (!p_sess->control_use_ssl)
    {
      vsf_sysutil_exit(0);
    }
    else
    {
      vsf_sysutil_clear_alarm();
      vsf_sysutil_close(p_sess->child_fd);
      if (tunable_setproctitle_enable)
      {
        vsf_sysutil_setproctitle("SSL handler");
      }
      process_ssl_slave_req(p_sess);
    }
    /* NOTREACHED */
  }
  else if (result == PRIV_SOCK_RESULT_BAD)
  {
    /* Continue the processing loop.. */
    return;
  }
  else
  {
    die("priv_sock_get_result");
  }
}
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");
    }
  }
}
Exemple #5
0
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");
    }
  }
}