Beispiel #1
0
/* server API */
enum SCP_SERVER_STATES_E scp_vXs_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s)
{
    tui32 version;

    /* reading version and packet size */
    if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
    {
        return SCP_SERVER_STATE_NETWORK_ERR;
    }

    in_uint32_be(c->in_s, version);

    if (version == 0)
    {
        return scp_v0s_accept(c, s, 1);
    }
    else if (version == 1)
    {
        return scp_v1s_accept(c, s, 1);
    }
    return SCP_SERVER_STATE_VERSION_ERR;
}
Beispiel #2
0
static enum SCP_CLIENT_STATES_E
_scp_v1c_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
{
	tui32 version;
	tui32 size;
	tui16 cmd;
	tui8 dim;
	char buf[257];

	init_stream(c->in_s, c->in_s->size);

	if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
	{
		log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
		return SCP_CLIENT_STATE_NETWORK_ERR;
	}

	in_uint32_be(c->in_s, version);

	if (version != 1)
	{
		log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__);
		return SCP_CLIENT_STATE_VERSION_ERR;
	}

	in_uint32_be(c->in_s, size);

	init_stream(c->in_s, c->in_s->size);

	/* read the rest of the packet */
	if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
	{
		log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
		return SCP_CLIENT_STATE_NETWORK_ERR;
	}

	in_uint16_be(c->in_s, cmd);

	if (cmd != SCP_COMMAND_SET_MANAGE)
	{
		log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
		return SCP_CLIENT_STATE_SEQUENCE_ERR;
	}

	in_uint16_be(c->in_s, cmd);

	if (cmd == SCP_CMD_MNG_LOGIN_ALLOW) /* connection ok */
	{
		log_message(LOG_LEVEL_INFO, "[v1c_mng:%d] connection ok", __LINE__);
		return SCP_CLIENT_STATE_OK;
	}
	else if (cmd == SCP_CMD_MNG_LOGIN_DENY) /* connection denied */
	{
		in_uint8(c->in_s, dim);
		buf[dim] = '\0';
		in_uint8a(c->in_s, buf, dim);
		scp_session_set_errstr(s, buf);

		log_message(LOG_LEVEL_INFO, "[v1c_mng:%d] connection denied: %s", __LINE__ , s->errstr);
		return SCP_CLIENT_STATE_CONNECTION_DENIED;
	}

	log_message(LOG_LEVEL_WARNING, "[v1c-mng:%d] connection aborted: sequence error", __LINE__);
	return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
Beispiel #3
0
/* 004 */
enum SCP_CLIENT_STATES_E
scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
		struct SCP_DISCONNECTED_SESSION **s)
{
	tui32 version = 1;
	tui32 size = 12;
	tui16 cmd = SCP_CMD_MNG_LIST_REQ;       /* request session list */
	tui32 sescnt = 0;    /* total session number */
	tui32 sestmp = 0;    /* additional total session number */
	tui8 pktcnt = 0;     /* packet session count */
	tui32 totalcnt = 0;  /* session counter */
	tui8 continued = 0;  /* continue flag */
	int firstpkt = 1;    /* "first packet" flag */
	int idx;
	struct SCP_DISCONNECTED_SESSION *ds = 0;
	//   tui8 addr[16];

	init_stream(c->out_s, c->out_s->size);

	/* we request session list */
	out_uint32_be(c->out_s, version);                 /* version */
	out_uint32_be(c->out_s, size);                    /* size    */
	out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE); /* cmdset  */
	out_uint16_be(c->out_s, cmd);                     /* cmd     */

	if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
	{
		log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
		return SCP_CLIENT_STATE_NETWORK_ERR;
	}

	do
	{
		/* then we wait for server response */
		init_stream(c->in_s, c->in_s->size);

		if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
		{
			log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
			return SCP_CLIENT_STATE_NETWORK_ERR;
		}

		in_uint32_be(c->in_s, version);

		if (version != 1)
		{
			log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__);
			return SCP_CLIENT_STATE_VERSION_ERR;
		}

		in_uint32_be(c->in_s, size);

		if (size < 12)
		{
			log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: size error", __LINE__);
			return SCP_CLIENT_STATE_SIZE_ERR;
		}

		init_stream(c->in_s, c->in_s->size);

		if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
		{
			log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
			return SCP_CLIENT_STATE_NETWORK_ERR;
		}

		in_uint16_be(c->in_s, cmd);

		if (cmd != SCP_COMMAND_SET_MANAGE)
		{
			log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
			return SCP_CLIENT_STATE_SEQUENCE_ERR;
		}

		in_uint16_be(c->in_s, cmd);

		if (cmd != SCP_CMD_MNG_LIST) /* session list */
		{
			log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
			return SCP_CLIENT_STATE_SEQUENCE_ERR;
		}

		if (firstpkt)
		{
			firstpkt = 0;
			in_uint32_be(c->in_s, sescnt);
			sestmp = sescnt;

			if (0 == sescnt)
			{
				/* return data... */
						(*scount) = sescnt;
						(*s) = NULL;

						LOG_DBG("[v1c_mng] end list - no session on TS");
						return SCP_CLIENT_STATE_LIST_OK;
			}

			ds = g_malloc(sizeof(struct SCP_DISCONNECTED_SESSION) * sescnt, 0);

			if (ds == 0)
			{
				log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: internal error", __LINE__);
				return SCP_CLIENT_STATE_INTERNAL_ERR;
			}
		}
		else
		{
			in_uint32_be(c->in_s, sestmp);
		}

		in_uint8(c->in_s, continued);
		in_uint8(c->in_s, pktcnt);

		for (idx = 0; idx < pktcnt; idx++)
		{
			in_uint32_be(c->in_s, (ds[totalcnt]).SID); /* session id */
			in_uint8(c->in_s, (ds[totalcnt]).type);
			in_uint16_be(c->in_s, (ds[totalcnt]).height);
			in_uint16_be(c->in_s, (ds[totalcnt]).width);
			in_uint8(c->in_s, (ds[totalcnt]).bpp);
			in_uint8(c->in_s, (ds[totalcnt]).idle_days);
			in_uint8(c->in_s, (ds[totalcnt]).idle_hours);
			in_uint8(c->in_s, (ds[totalcnt]).idle_minutes);

			in_uint16_be(c->in_s, (ds[totalcnt]).conn_year);
			in_uint8(c->in_s, (ds[totalcnt]).conn_month);
			in_uint8(c->in_s, (ds[totalcnt]).conn_day);
			in_uint8(c->in_s, (ds[totalcnt]).conn_hour);
			in_uint8(c->in_s, (ds[totalcnt]).conn_minute);
			in_uint8(c->in_s, (ds[totalcnt]).addr_type);

			if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV4)
			{
				in_uint32_be(c->in_s, (ds[totalcnt]).ipv4addr);
			}

			if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV6)
			{
				in_uint8a(c->in_s, (ds[totalcnt]).ipv6addr, 16);
			}

			totalcnt++;
		}
	}
	while (continued);

	/* return data... */
	(*scount) = sescnt;
	(*s) = ds;

	LOG_DBG("[v1c_mng] end list");
	return SCP_CLIENT_STATE_LIST_OK;
}
Beispiel #4
0
/* 041 */
enum SCP_CLIENT_STATES_E
scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount,
                         struct SCP_DISCONNECTED_SESSION **s)
{
    tui32 version = 1;
    tui32 size = 12;
    tui16 cmd = 41;
    tui32 sescnt = 0;    /* total session number */
    tui32 sestmp = 0;    /* additional total session number */
    tui8 pktcnt = 0;     /* packet session count */
    tui32 totalcnt = 0;  /* session counter */
    tui8 continued = 0;  /* continue flag */
    int firstpkt = 1;    /* "first packet" flag */
    int idx;
    struct SCP_DISCONNECTED_SESSION *ds = 0;

    init_stream(c->out_s, c->out_s->size);

    /* we request session list */
    out_uint32_be(c->out_s, version);                 /* version */
    out_uint32_be(c->out_s, size);                    /* size    */
    out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset  */
    out_uint16_be(c->out_s, cmd);                     /* cmd     */

    if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
    {
        return SCP_CLIENT_STATE_NETWORK_ERR;
    }

    do
    {
        /* then we wait for server response */
        init_stream(c->in_s, c->in_s->size);

        if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
        {
            return SCP_CLIENT_STATE_NETWORK_ERR;
        }

        in_uint32_be(c->in_s, version);

        if (version != 1)
        {
            return SCP_CLIENT_STATE_VERSION_ERR;
        }

        in_uint32_be(c->in_s, size);

        if (size < 12)
        {
            return SCP_CLIENT_STATE_SIZE_ERR;
        }

        init_stream(c->in_s, c->in_s->size);

        if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
        {
            return SCP_CLIENT_STATE_NETWORK_ERR;
        }

        in_uint16_be(c->in_s, cmd);

        if (cmd != SCP_COMMAND_SET_DEFAULT)
        {
            return SCP_CLIENT_STATE_SEQUENCE_ERR;
        }

        in_uint16_be(c->in_s, cmd);

        if (cmd != 42)
        {
            return SCP_CLIENT_STATE_SEQUENCE_ERR;
        }

        if (firstpkt)
        {
            firstpkt = 0;
            in_uint32_be(c->in_s, sescnt);
            sestmp = sescnt;

            ds = g_new(struct SCP_DISCONNECTED_SESSION, sescnt);

            if (ds == 0)
            {
                return SCP_CLIENT_STATE_INTERNAL_ERR;
            }
        }
        else
        {
            in_uint32_be(c->in_s, sestmp);
        }

        in_uint8(c->in_s, continued);
        in_uint8(c->in_s, pktcnt);

        for (idx = 0; idx < pktcnt; idx++)
        {
            in_uint32_be(c->in_s, (ds[totalcnt]).SID); /* session id */
            in_uint8(c->in_s, (ds[totalcnt]).type);
            in_uint16_be(c->in_s, (ds[totalcnt]).height);
            in_uint16_be(c->in_s, (ds[totalcnt]).width);
            in_uint8(c->in_s, (ds[totalcnt]).bpp);
            in_uint8(c->in_s, (ds[totalcnt]).idle_days);
            in_uint8(c->in_s, (ds[totalcnt]).idle_hours);
            in_uint8(c->in_s, (ds[totalcnt]).idle_minutes);

            in_uint16_be(c->in_s, (ds[totalcnt]).conn_year);
            in_uint8(c->in_s, (ds[totalcnt]).conn_month);
            in_uint8(c->in_s, (ds[totalcnt]).conn_day);
            in_uint8(c->in_s, (ds[totalcnt]).conn_hour);
            in_uint8(c->in_s, (ds[totalcnt]).conn_minute);
            in_uint8(c->in_s, (ds[totalcnt]).addr_type);

            if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV4)
            {
                in_uint32_be(c->in_s, (ds[totalcnt]).ipv4addr);
            }
            else if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV6)
            {
                in_uint8a(c->in_s, (ds[totalcnt]).ipv6addr, 16);
            }

            totalcnt++;
        }
    }
Beispiel #5
0
/* 040 */
enum SCP_SERVER_STATES_E
scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNECTED_SESSION* ds, SCP_SID* sid)
{
  tui32 version=1;
  tui32 size=12;
  tui16 cmd=40;
  int pktcnt;
  int idx;
  int sidx;
  int pidx;
  struct SCP_DISCONNECTED_SESSION* cds;

  /* first we send a notice that we have some disconnected sessions */
  init_stream(c->out_s, c->out_s->size);

  out_uint32_be(c->out_s, version);                 /* version */
  out_uint32_be(c->out_s, size);                    /* size    */
  out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset  */
  out_uint16_be(c->out_s, cmd);                     /* cmd     */

  if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size))
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
    return SCP_SERVER_STATE_NETWORK_ERR;
  }

  /* then we wait for client ack */
#warning maybe this message could say if the session should be resized on
#warning server side or client side
  init_stream(c->in_s, c->in_s->size);
  if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
    return SCP_SERVER_STATE_NETWORK_ERR;
  }

  in_uint32_be(c->in_s, version);
  if (version!=1)
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
    return SCP_SERVER_STATE_VERSION_ERR;
  }

  in_uint32_be(c->in_s, size);
  if (size<12)
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
    return SCP_SERVER_STATE_SIZE_ERR;
  }

  init_stream(c->in_s, c->in_s->size);
  if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8)))
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
    return SCP_SERVER_STATE_NETWORK_ERR;
  }

  in_uint16_be(c->in_s, cmd);
  if (cmd != SCP_COMMAND_SET_DEFAULT)
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
    return SCP_SERVER_STATE_SEQUENCE_ERR;
  }

  in_uint16_be(c->in_s, cmd);
  if (cmd != 41)
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
    return SCP_SERVER_STATE_SEQUENCE_ERR;
  }

  /* calculating the number of packets to send */
  pktcnt=sescnt/SCP_SERVER_MAX_LIST_SIZE;
  if ((sescnt%SCP_SERVER_MAX_LIST_SIZE)!=0)
  {
    pktcnt++;
  }

  for (idx=0; idx<pktcnt; idx++)
  {
    /* ok, we send session session list */
    init_stream(c->out_s, c->out_s->size);

    /* size: ver+size+cmdset+cmd+sescnt+continue+count */
    size=4+4+2+2+4+1+1;

    /* header */
    cmd=42;
    s_push_layer(c->out_s, channel_hdr, 8);
    out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT);
    out_uint16_be(c->out_s, cmd);

    /* session count */
    out_uint32_be(c->out_s, sescnt);

    /* setting the continue flag */
    if ((idx+1)*SCP_SERVER_MAX_LIST_SIZE >= sescnt)
    {
      out_uint8(c->out_s, 0);
      /* setting session count for this packet */
      pidx=sescnt-(idx*SCP_SERVER_MAX_LIST_SIZE);
      out_uint8(c->out_s, pidx);
    }
    else
    {
      out_uint8(c->out_s, 1);
      /* setting session count for this packet */
      pidx=SCP_SERVER_MAX_LIST_SIZE;
      out_uint8(c->out_s, pidx);
    }

    /* adding session descriptors */
    for (sidx=0; sidx<pidx; sidx++)
    {
      /* shortcut to the current session to send */
      cds=ds+((idx)*SCP_SERVER_MAX_LIST_SIZE)+sidx;

      /* session data */
      out_uint32_be(c->out_s, cds->SID); /* session id */
      out_uint8(c->out_s, cds->type);
      out_uint16_be(c->out_s, cds->height);
      out_uint16_be(c->out_s, cds->width);
      out_uint8(c->out_s, cds->bpp);
      out_uint8(c->out_s, cds->idle_days);
      out_uint8(c->out_s, cds->idle_hours);
      out_uint8(c->out_s, cds->idle_minutes);
      size += 13;

      out_uint16_be(c->out_s, cds->conn_year);
      out_uint8(c->out_s, cds->conn_month);
      out_uint8(c->out_s, cds->conn_day);
      out_uint8(c->out_s, cds->conn_hour);
      out_uint8(c->out_s, cds->conn_minute);
      out_uint8(c->out_s, cds->addr_type);
      size += 7;

      if (cds->addr_type == SCP_ADDRESS_TYPE_IPV4)
      {
        in_uint32_be(c->out_s, cds->ipv4addr);
        size += 4;
      }
      else if (cds->addr_type == SCP_ADDRESS_TYPE_IPV6)
      {
        in_uint8a(c->out_s, cds->ipv6addr, 16);
        size += 16;
      }
    }

    s_pop_layer(c->out_s, channel_hdr);
    out_uint32_be(c->out_s, version);
    out_uint32_be(c->out_s, size);

    if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
    {
      log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
      return SCP_SERVER_STATE_NETWORK_ERR;
    }
  }

  /* we get the response */
  init_stream(c->in_s, c->in_s->size);
  if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (8)))
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
    return SCP_SERVER_STATE_NETWORK_ERR;
  }

  in_uint32_be(c->in_s, version);
  if (version != 1)
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
    return SCP_SERVER_STATE_VERSION_ERR;
  }

  in_uint32_be(c->in_s, size);
  if (size < 12)
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
    return SCP_SERVER_STATE_SIZE_ERR;
  }

  /* rest of the packet */
  init_stream(c->in_s, c->in_s->size);
  if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8)))
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
    return SCP_SERVER_STATE_NETWORK_ERR;
  }

  in_uint16_be(c->in_s, cmd);
  if (cmd != SCP_COMMAND_SET_DEFAULT)
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
    return SCP_SERVER_STATE_SEQUENCE_ERR;
  }

  in_uint16_be(c->in_s, cmd);
  if (cmd == 43)
  {
    /* select session */
    in_uint32_be(c->in_s, (*sid));

    /* checking sid value */
    for (idx=0; idx<sescnt; idx++)
    {
      /* the sid is valid */
      if (ds[idx].SID==(*sid))
      {
        /* ok, session selected */
        return SCP_SERVER_STATE_OK;
      }
    }

    /* if we got here, the requested sid wasn't one from the list we sent */
    /* we should kill the connection                                      */
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (no such session in list)", __LINE__);
    return SCP_CLIENT_STATE_INTERNAL_ERR;
  }
  else if (cmd == 44)
  {
    /* cancel connection */
    return SCP_SERVER_STATE_SELECTION_CANCEL;
  }
//  else if (cmd == 45)
//  {
//    /* force new connection */
//    return SCP_SERVER_STATE_FORCE_NEW;
//  }
  else
  {
    /* wrong response */
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
    return SCP_SERVER_STATE_SEQUENCE_ERR;
  }

  return SCP_SERVER_STATE_OK;
}
Beispiel #6
0
/* server API */
enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk)
{
  struct SCP_SESSION* session;
  tui32 version;
  tui32 size;
  tui16 cmdset;
  tui16 cmd;
  tui8 sz;
  char buf[257];

  if (!skipVchk)
  {

    if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
    {
      in_uint32_be(c->in_s, version);
      if (version != 1)
      {
        log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
        return SCP_SERVER_STATE_VERSION_ERR;
      }
    }
    else
    {
      log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
      return SCP_SERVER_STATE_NETWORK_ERR;
    }
  }

  in_uint32_be(c->in_s, size);
  if (size < 12)
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
    return SCP_SERVER_STATE_SIZE_ERR;
  }

  init_stream(c->in_s, c->in_s->size);
  if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8)))
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
    return SCP_SERVER_STATE_NETWORK_ERR;
  }

  /* reading command set */
  in_uint16_be(c->in_s, cmdset);

  /* if we are starting a management session */
  if (cmdset == SCP_COMMAND_SET_MANAGE)
  {
    log_message(LOG_LEVEL_DEBUG, "[v1s:%d] requested management connection", __LINE__);
    /* should return SCP_SERVER_STATE_START_MANAGE */
    return scp_v1s_mng_accept(c, s);
  }

  /* if we started with resource sharing... */
  if (cmdset == SCP_COMMAND_SET_RSR)
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
    return SCP_SERVER_STATE_SEQUENCE_ERR;
  }

  /* reading command */
  in_uint16_be(c->in_s, cmd);
  if (cmd != 1)
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
    return SCP_SERVER_STATE_SEQUENCE_ERR;
  }

  session = scp_session_create();
  if (0 == session)
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (malloc returned NULL)", __LINE__);
    return SCP_SERVER_STATE_INTERNAL_ERR;
  }
  scp_session_set_version(session, 1);

  in_uint8(c->in_s, sz);
  if ((sz != SCP_SESSION_TYPE_XVNC) && (sz != SCP_SESSION_TYPE_XRDP))
  {
    scp_session_destroy(session);
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: unknown session type", __LINE__);
    return SCP_SERVER_STATE_SESSION_TYPE_ERR;
  }
  scp_session_set_type(session, sz);

  in_uint16_be(c->in_s, cmd);
  scp_session_set_height(session, cmd);
  in_uint16_be(c->in_s, cmd);
  scp_session_set_height(session, cmd);
  in_uint8(c->in_s, sz);
  scp_session_set_bpp(session, sz);
  in_uint8(c->in_s, sz);
  scp_session_set_rsr(session, sz);
  in_uint8a(c->in_s, buf, 17);
    buf[17]='\0';
  scp_session_set_locale(session, buf);

  in_uint8(c->in_s, sz);
  if (sz == SCP_ADDRESS_TYPE_IPV4)
  {
    in_uint32_be(c->in_s, size);
    scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV4_BIN, &size);
  }
  else if (sz == SCP_ADDRESS_TYPE_IPV6)
  {
    in_uint8a(c->in_s, buf, 16);
    scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV6_BIN, buf);
  }

  buf[256] = '\0';
  /* reading hostname */
  in_uint8(c->in_s, sz);
  buf[sz]='\0';
  in_uint8a(c->in_s, buf, sz);
  if (0 != scp_session_set_hostname(session, buf))
  {
    scp_session_destroy(session);
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
    return SCP_SERVER_STATE_INTERNAL_ERR;
  }

  /* reading username */
  in_uint8(c->in_s, sz);
  buf[sz]='\0';
  in_uint8a(c->in_s, buf, sz);
  if (0 != scp_session_set_username(session, buf))
  {
    scp_session_destroy(session);
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
    return SCP_SERVER_STATE_INTERNAL_ERR;
  }

  /* reading password */
  in_uint8(c->in_s, sz);
  buf[sz]='\0';
  in_uint8a(c->in_s, buf, sz);
  if (0 != scp_session_set_password(session, buf))
  {
    scp_session_destroy(session);
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
    return SCP_SERVER_STATE_INTERNAL_ERR;
  }

  /* returning the struct */
  (*s)=session;

  return SCP_SERVER_STATE_OK;
}
Beispiel #7
0
enum SCP_SERVER_STATES_E
scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char* reason)
{
  tui8 sz;
  tui32 version;
  tui32 size;
  tui16 cmdset;
  tui16 cmd;
  int rlen;
  char buf[257];

  init_stream(c->in_s, c->in_s->size);
  init_stream(c->out_s, c->out_s->size);

  /* forcing message not to exceed 64k */
  rlen = g_strlen(reason);
  if (rlen > 65535)
  {
    rlen = 65535;
  }

  /* send password request */
  version=1;
  cmd=3;

  out_uint32_be(c->out_s, version);                 /* version */
  out_uint32_be(c->out_s, 14+rlen);                 /* size    */
  out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset  */
  out_uint16_be(c->out_s, cmd);                     /* cmd     */

  out_uint16_be(c->out_s, rlen);
  out_uint8p(c->out_s, reason, rlen);

  if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, 14+rlen))
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
    return SCP_SERVER_STATE_NETWORK_ERR;
  }

  /* receive password & username */
  if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
    return SCP_SERVER_STATE_NETWORK_ERR;
  }

  in_uint32_be(c->in_s, version);
  if (version!=1)
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
    return SCP_SERVER_STATE_VERSION_ERR;
  }

  in_uint32_be(c->in_s, size);
  if (size<12)
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
    return SCP_SERVER_STATE_SIZE_ERR;
  }

  init_stream(c->in_s, c->in_s->size);
  if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8)))
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
    return SCP_SERVER_STATE_NETWORK_ERR;
  }

  in_uint16_be(c->in_s, cmdset);
  if (cmdset != SCP_COMMAND_SET_DEFAULT)
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
    return SCP_SERVER_STATE_SEQUENCE_ERR;
  }

  in_uint16_be(c->in_s, cmd);
  if (cmd != 4)
  {
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
    return SCP_SERVER_STATE_SEQUENCE_ERR;
  }

  buf[256] = '\0';
  /* reading username */
  in_uint8(c->in_s, sz);
  buf[sz] = '\0';
  in_uint8a(c->in_s, buf, sz);
  if (0 != scp_session_set_username(s, buf))
  {
    scp_session_destroy(s);
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
    return SCP_SERVER_STATE_INTERNAL_ERR;
  }

  /* reading password */
  in_uint8(c->in_s, sz);
  buf[sz]='\0';
  in_uint8a(c->in_s, buf, sz);
  if (0 != scp_session_set_password(s, buf))
  {
    scp_session_destroy(s);
    log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
    return SCP_SERVER_STATE_INTERNAL_ERR;
  }

  return SCP_SERVER_STATE_OK;
}
Beispiel #8
0
enum SCP_CLIENT_STATES_E
scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
{
    tui32 version;
    tui32 size;
    tui16 sz;

    init_stream(c->in_s, c->in_s->size);
    init_stream(c->out_s, c->in_s->size);

    LOG_DBG("[v0:%d] starting connection", __LINE__);
    g_tcp_set_non_blocking(c->in_sck);
    g_tcp_set_no_delay(c->in_sck);
    s_push_layer(c->out_s, channel_hdr, 8);

    /* code */
    if (s->type == SCP_SESSION_TYPE_XVNC)
    {
        out_uint16_be(c->out_s, 0);
    }
    else if (s->type == SCP_SESSION_TYPE_XRDP)
    {
        out_uint16_be(c->out_s, 10);
    }
    else if (s->type == SCP_SESSION_TYPE_XORG)
    {
        out_uint16_be(c->out_s, 20);
    }
    else
    {
        log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
        return SCP_CLIENT_STATE_INTERNAL_ERR;
    }

    sz = g_strlen(s->username);
    out_uint16_be(c->out_s, sz);
    out_uint8a(c->out_s, s->username, sz);

    sz = g_strlen(s->password);
    out_uint16_be(c->out_s, sz);
    out_uint8a(c->out_s, s->password, sz);
    out_uint16_be(c->out_s, s->width);
    out_uint16_be(c->out_s, s->height);
    out_uint16_be(c->out_s, s->bpp);

    s_mark_end(c->out_s);
    s_pop_layer(c->out_s, channel_hdr);

    /* version */
    out_uint32_be(c->out_s, 0);
    /* size */
    out_uint32_be(c->out_s, c->out_s->end - c->out_s->data);

    if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
    {
        log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
        return SCP_CLIENT_STATE_NETWORK_ERR;
    }

    if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
    {
        log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
        return SCP_CLIENT_STATE_NETWORK_ERR;
    }

    in_uint32_be(c->in_s, version);

    if (0 != version)
    {
        log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__);
        return SCP_CLIENT_STATE_VERSION_ERR;
    }

    in_uint32_be(c->in_s, size);

    if (size < 14)
    {
        log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: packet size error", __LINE__);
        return SCP_CLIENT_STATE_SIZE_ERR;
    }

    /* getting payload */
    init_stream(c->in_s, c->in_s->size);

    if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
    {
        log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
        return SCP_CLIENT_STATE_NETWORK_ERR;
    }

    /* check code */
    in_uint16_be(c->in_s, sz);

    if (3 != sz)
    {
        log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__);
        return SCP_CLIENT_STATE_SEQUENCE_ERR;
    }

    /* message payload */
    in_uint16_be(c->in_s, sz);

    if (1 != sz)
    {
        log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: connection denied", __LINE__);
        return SCP_CLIENT_STATE_CONNECTION_DENIED;
    }

    in_uint16_be(c->in_s, sz);
    s->display = sz;

    LOG_DBG("[v0:%d] connection terminated", __LINE__);
    return SCP_CLIENT_STATE_END;
}
Beispiel #9
0
enum SCP_SERVER_STATES_E
scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk)
{
    tui32 version = 0;
    tui32 size;
    struct SCP_SESSION *session = 0;
    tui16 sz;
    tui32 code = 0;
    char buf[257];

    if (!skipVchk)
    {
        LOG_DBG("[v0:%d] starting connection", __LINE__);

        if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
        {
            c->in_s->end = c->in_s->data + 8;
            in_uint32_be(c->in_s, version);

            if (version != 0)
            {
                log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__);
                return SCP_SERVER_STATE_VERSION_ERR;
            }
        }
        else
        {
            log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
            return SCP_SERVER_STATE_NETWORK_ERR;
        }
    }

    in_uint32_be(c->in_s, size);

    init_stream(c->in_s, 8196);

    if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
    {
        log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
        return SCP_SERVER_STATE_NETWORK_ERR;
    }

    c->in_s->end = c->in_s->data + (size - 8);

    in_uint16_be(c->in_s, code);

    if (code == 0 || code == 10 || code == 20)
    {
        session = scp_session_create();

        if (0 == session)
        {
            log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
            return SCP_SERVER_STATE_INTERNAL_ERR;
        }

        scp_session_set_version(session, version);

        if (code == 0)
        {
            scp_session_set_type(session, SCP_SESSION_TYPE_XVNC);
        }
        else if (code == 10)
        {
            scp_session_set_type(session, SCP_SESSION_TYPE_XRDP);
        }
        else if (code == 20)
        {
            scp_session_set_type(session, SCP_SESSION_TYPE_XORG);
        }

        /* reading username */
        in_uint16_be(c->in_s, sz);
        buf[sz] = '\0';
        in_uint8a(c->in_s, buf, sz);

        if (0 != scp_session_set_username(session, buf))
        {
            scp_session_destroy(session);
            log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);
            return SCP_SERVER_STATE_INTERNAL_ERR;
        }

        /* reading password */
        in_uint16_be(c->in_s, sz);
        buf[sz] = '\0';
        in_uint8a(c->in_s, buf, sz);

        if (0 != scp_session_set_password(session, buf))
        {
            scp_session_destroy(session);
            log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__);
            return SCP_SERVER_STATE_INTERNAL_ERR;
        }

        /* width */
        in_uint16_be(c->in_s, sz);
        scp_session_set_width(session, sz);
        /* height */
        in_uint16_be(c->in_s, sz);
        scp_session_set_height(session, sz);
        /* bpp */
        in_uint16_be(c->in_s, sz);
        scp_session_set_bpp(session, (tui8)sz);

        if (s_check_rem(c->in_s, 2))
        {
            /* reading domain */
            in_uint16_be(c->in_s, sz);

            if (sz > 0)
            {
                in_uint8a(c->in_s, buf, sz);
                buf[sz] = '\0';
                scp_session_set_domain(session, buf);
            }
        }

        if (s_check_rem(c->in_s, 2))
        {
            /* reading program */
            in_uint16_be(c->in_s, sz);

            if (sz > 0)
            {
                in_uint8a(c->in_s, buf, sz);
                buf[sz] = '\0';
                scp_session_set_program(session, buf);
            }
        }

        if (s_check_rem(c->in_s, 2))
        {
            /* reading directory */
            in_uint16_be(c->in_s, sz);

            if (sz > 0)
            {
                in_uint8a(c->in_s, buf, sz);
                buf[sz] = '\0';
                scp_session_set_directory(session, buf);
            }
        }

        if (s_check_rem(c->in_s, 2))
        {
            /* reading client IP address */
            in_uint16_be(c->in_s, sz);

            if (sz > 0)
            {
                in_uint8a(c->in_s, buf, sz);
                buf[sz] = '\0';
                scp_session_set_client_ip(session, buf);
            }
        }
    }
    else if (code == SCP_GW_AUTHENTICATION)
    {
        /* g_writeln("Command is SCP_GW_AUTHENTICATION"); */
        session = scp_session_create();

        if (0 == session)
        {
            /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error",      __LINE__);*/
            return SCP_SERVER_STATE_INTERNAL_ERR;
        }

        scp_session_set_version(session, version);
        scp_session_set_type(session, SCP_GW_AUTHENTICATION);
        /* reading username */
        in_uint16_be(c->in_s, sz);
        buf[sz] = '\0';
        in_uint8a(c->in_s, buf, sz);

        /* g_writeln("Received user name: %s",buf); */
        if (0 != scp_session_set_username(session, buf))
        {
            scp_session_destroy(session);
            /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting        username", __LINE__);*/
            return SCP_SERVER_STATE_INTERNAL_ERR;
        }

        /* reading password */
        in_uint16_be(c->in_s, sz);
        buf[sz] = '\0';
        in_uint8a(c->in_s, buf, sz);

        /* g_writeln("Received password: %s",buf); */
        if (0 != scp_session_set_password(session, buf))
        {
            scp_session_destroy(session);
            /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); */
            return SCP_SERVER_STATE_INTERNAL_ERR;
        }
    }
    else
    {
        log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__);
        return SCP_SERVER_STATE_SEQUENCE_ERR;
    }

    (*s) = session;
    return SCP_SERVER_STATE_OK;
}
Beispiel #10
0
static enum SCP_SERVER_STATES_E
_scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
{
    tui32 version;
    tui32 size;
    tui16 cmd;
    //   tui8 dim;
    //   char buf[257];

    init_stream(c->in_s, c->in_s->size);

    if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
    {
        log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
        return SCP_SERVER_STATE_NETWORK_ERR;
    }

    in_uint32_be(c->in_s, version);

    if (version != 1)
    {
        log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: version error", __LINE__);
        return SCP_SERVER_STATE_VERSION_ERR;
    }

    in_uint32_be(c->in_s, size);

    init_stream(c->in_s, c->in_s->size);

    /* read the rest of the packet */
    if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
    {
        log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
        return SCP_SERVER_STATE_NETWORK_ERR;
    }

    in_uint16_be(c->in_s, cmd);

    if (cmd != SCP_COMMAND_SET_MANAGE)
    {
        log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__);
        return SCP_SERVER_STATE_SEQUENCE_ERR;
    }

    in_uint16_be(c->in_s, cmd);

    if (cmd == SCP_CMD_MNG_LIST_REQ) /* request session list */
    {
        log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] request session list", __LINE__);
        return SCP_SERVER_STATE_MNG_LISTREQ;
    }
    else if (cmd == SCP_CMD_MNG_ACTION) /* execute an action */
    {
        /*in_uint8(c->in_s, dim);
        buf[dim]='\0';
        in_uint8a(c->in_s, buf, dim);
        scp_session_set_errstr(s, buf);*/

        log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] action request", __LINE__);
        return SCP_SERVER_STATE_MNG_ACTION;
    }

    /* else if (cmd == 20) / * password change * /
    {
      in_uint16_be(c->in_s, s->display);

      return SCP_SERVER_STATE_OK;
    }
    else if (cmd == 40) / * session list * /
    {
      return SCP_SERVER_STATE_SESSION_LIST;
    }*/

    log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__);
    return SCP_SERVER_STATE_SEQUENCE_ERR;
}