Exemple #1
0
int get_transfer_fd(session_t *pses)
{
    int iret = 0;
    //可能是主动模式,或者被动模式
    //检测是否收到PORT命令或者PASV命令
    if((port_active(pses) < 0) && (pasv_active(pses) < 0))
    {
        ftp_reply(pses->ctrl_fd, FTP_BADSENDCONN, "Use PORT or PASV first.");
        iret = -1;
        return iret;
    }

    //主动模式
    if(port_active(pses) == 0)
    {
        //向nobody进程发送命令
        priv_sock_send_cmd(pses->child_fd, PRIV_SOCK_GET_DATA_SOCK);
        unsigned short port = ntohs(pses->port_addr->sin_port);
        char *ip = inet_ntoa(pses->port_addr->sin_addr);
        //发送port
        priv_sock_send_int(pses->child_fd, (int)port);
        //发送ip
        priv_sock_send_buf(pses->child_fd, ip, strlen(ip));

        //接收应答
        char res = priv_sock_get_result(pses->child_fd);
        if(res == PRIV_SOCK_RESULT_BAD)
        {
            iret = -1;
        }
        else if(res == PRIV_SOCK_RESULT_OK)
        {
            //接收文件描述符
            pses->data_fd = priv_sock_recv_fd(pses->child_fd);
        }
    }
    else if(pasv_active(pses) == 0)//被动模式
    {
        //发送命令给nobody进程,完成客户端和服务端的连接
        priv_sock_send_cmd(pses->child_fd, PRIV_SOCK_PASV_ACCEPT);
        //接收nobody进程的应答
        char res = priv_sock_get_result(pses->child_fd);
        if(res == PRIV_SOCK_RESULT_BAD)
        {
            iret = -1;
        }
        else if(res == PRIV_SOCK_RESULT_OK)
        {
            pses->data_fd = priv_sock_recv_fd(pses->child_fd);
        }
    }
    //连接成功后,该内存空间就不需要了
    if(pses->port_addr != NULL)
    {
        free(pses->port_addr);
        pses->port_addr = NULL;
    }
    return iret;
}
Exemple #2
0
static void privop_pasv_active(session_t *sess)
{
	int active;
	if (sess->pasv_listen_fd != -1)
		active = 1;
	else
		active = 0;
	priv_sock_send_int(sess->nobody_fd, active);
}
Exemple #3
0
/**
 * 发送字符串,先发送长度
 * @param fd  [description]
 * @param buf [description]
 * @param len 字符串的长度
 */
void priv_sock_send_buf(int fd, const char *buf, unsigned int len)
{
	priv_sock_send_int(fd, (int)len);
	int ret = sysutil::writen(fd, buf, len);
	if (ret != (int)len)
	{
		FTPD_LOG(ERROR,"priv_sock_send_buf error\n");
	}
}
Exemple #4
0
void priv_sock_send_buf(int fd, const char *buf, unsigned int len)
{
    priv_sock_send_int(fd, (int)len);
    int ret = writen(fd, buf, len);
    if (ret != (int)len)
    {
        fprintf(stderr, "priv_sock_send_buf error\n");
        exit(EXIT_FAILURE);
    }
}
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");
  }
}
Exemple #6
0
/*发送一个字符串*/
void priv_sock_send_buf(int fd, const char *buf, unsigned int len)
{
	/*先发送字符串的长度*/
	priv_sock_send_int(fd, len);
	/*发送字符串*/
	int ret = writen(fd, buf, len);
	if (ret != (int)len)
	{
		fprintf(stderr, "priv_sock_send_buf error");
		exit(EXIT_FAILURE);
	}	
}
static void privop_pasv_listen(session_t *sess)
{
	sess->pasv_listen_fd = tcp_server(tunable_listen_address, 0);
	struct sockaddr_in addr;
	socklen_t addrlen = sizeof(addr);
	if (getsockname(sess->pasv_listen_fd, (struct sockaddr *)&addr, &addrlen) < 0)
	{
		priv_sock_send_result(sess->parent_fd, PRIV_SOCK_RESULT_BAD);
		ERR_EXIT("getsockname");
	}
	
	priv_sock_send_result(sess->parent_fd, PRIV_SOCK_RESULT_OK);
	priv_sock_send_int(sess->parent_fd, (int)addr.sin_port);
}
Exemple #8
0
void PrivPar::privop_pasv_active(session_t *sess)
{
	int active;
	if (sess->pasv_listen_fd != -1)
	{
		active = 1;
	}
	else
	{
		active = 0;
	}

	priv_sock_send_int(sess->parent_fd, active);
}
Exemple #9
0
static void privop_pasv_listen(session_t *sess)
{
	char ip[20] = {0};
	getlocalip(ip);
	// 服务器 bind 的必须是随机端口,因此此时可能有多个nobody 进程在listen, 这样才不会冲突
	sess->pasv_listen_fd = tcp_server(ip, 0);
	struct sockaddr_in localaddr;
	socklen_t addrlen = sizeof(localaddr);
	if (getsockname(sess->pasv_listen_fd, (struct sockaddr *)&localaddr, &addrlen) < 0)
		ERR_EXIT("getsockname");

	unsigned short port = ntohs(localaddr.sin_port);

	priv_sock_send_int(sess->nobody_fd, (int)port);
}
Exemple #10
0
static void privop_pasv_listen(session_t *sess)
{
    char ip[16];
    getlocalip(ip);

    sess->pasv_listen_fd = tcp_server(ip, 0);
    struct sockaddr_in addr;
    socklen_t addrlen = sizeof(addr);
    if(getsockname(sess->pasv_listen_fd, (struct sockaddr *)&addr, &addrlen) < 0)
    {
        ERR_EXIT("getsockname");
    }

    unsigned short port = ntohs(addr.sin_port);
    priv_sock_send_int(sess->parent_fd, (int)port);
}
Exemple #11
0
int get_port_fd(session_t* sess)
{
	priv_sock_send_cmd(sess->child_fd, PRIV_SOCK_GET_DATA_SOCK);
        unsigned short port = ntohs(sess->port_addr->sin_port);
        char* ip = inet_ntoa(sess->port_addr->sin_addr);

        priv_sock_send_int(sess->child_fd, (int)port);
        priv_sock_send_buf(sess->child_fd, ip, strlen(ip));

        char res = priv_sock_get_result(sess->child_fd);
        if(res == PRIV_SOCK_RESULT_BAD)
         	return 0;

        else if(res == PRIV_SOCK_RESULT_OK)
                sess->data_fd = priv_sock_recv_fd(sess->child_fd);
	
	return 1;
}
int
vsf_two_process_get_priv_data_sock(struct vsf_session* p_sess)
{
  char res;
  unsigned short port = vsf_sysutil_sockaddr_get_port(p_sess->p_port_sockaddr);
  priv_sock_send_cmd(p_sess->child_fd, PRIV_SOCK_GET_DATA_SOCK);
  priv_sock_send_int(p_sess->child_fd, port);
  res = priv_sock_get_result(p_sess->child_fd);
  if (res == PRIV_SOCK_RESULT_BAD)
  {
    return -1;
  }
  else if (res != PRIV_SOCK_RESULT_OK)
  {
    die("could not get privileged socket");
  }
  return priv_sock_recv_fd(p_sess->child_fd);
}
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 #14
0
void priv_sock_send_str(int fd, const char *str, int len)
{
	priv_sock_send_int(fd, len);
	if (writen(fd, str, len) != len)
		ERROR_EXIT("writen");
}
Exemple #15
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");
    }
  }
}