Exemple #1
0
int main(int ac, char **av)
{
  unsigned int pass, i;
  SshBuffer buffer, buffer2;
  SocksInfo socksinfo, socksreturn;
  SocksError ret;

  ssh_buffer_init(&buffer);
  ssh_buffer_init(&buffer2);
  for(pass = 0; pass < 20000; pass++)
    {
      ssh_buffer_clear(&buffer);
      socksinfo = ssh_xmalloc(sizeof(struct SocksInfoRec));
      socksinfo->socks_version_number = 4;
      socksinfo->command_code = (pass & 1) + 1;
      socksinfo->ip =
	ssh_xstrdup(ip_numbers[pass % (sizeof(ip_numbers) /
				   sizeof(ip_numbers[0]))]);
      socksinfo->port =
	ssh_xstrdup(port_numbers[pass % (sizeof(port_numbers) /
				     sizeof(port_numbers[0]))]);
      socksinfo->username =
	ssh_xstrdup(usernames[pass % (sizeof(usernames) /
				  sizeof(usernames[0]))]);
      if (ssh_socks_client_generate_open(&buffer, socksinfo) !=
	  SSH_SOCKS_SUCCESS)
	ssh_fatal("ssh_socks_client_generate_open fails");
      if (pass & 1)
	{
	  unsigned char *p;
	  unsigned int len;
	  
	  ssh_buffer_clear(&buffer2);
	  p = ssh_buffer_ptr(&buffer);
	  len = ssh_buffer_len(&buffer);
	  /* Give partial buffer */
	  for(i = 0; i + 1 < len; i++)
	    {
	      ssh_buffer_append(&buffer2, p + i, 1);
	      if (ssh_socks_server_parse_open(&buffer2, &socksreturn) !=
		  SSH_SOCKS_TRY_AGAIN)
		ssh_fatal("ssh_socks_server_parse_open fails in partial data (should return try_again)");
	    }
	  ssh_buffer_append(&buffer2, p + i, 1);
	  if (ssh_socks_server_parse_open(&buffer2, &socksreturn) !=
	      SSH_SOCKS_SUCCESS)
	    ssh_fatal("ssh_socks_server_parse_open fails for partial data (should return success)");
          if (ssh_buffer_len(&buffer2) != 0)
	    ssh_fatal("Junk left to buffer after server_parse_open");
	}
      else
	{
	  if (ssh_socks_server_parse_open(&buffer, &socksreturn) !=
	      SSH_SOCKS_SUCCESS)
	    ssh_fatal("ssh_socks_server_parse_open fails for partial data (should return success)");
          if (ssh_buffer_len(&buffer) != 0)
	    ssh_fatal("Junk left to buffer after server_parse_open");
	}
      if (socksinfo->socks_version_number != socksreturn->socks_version_number)
	ssh_fatal("socks_version_numbers differ request");
      if (socksinfo->command_code != socksreturn->command_code)
	ssh_fatal("command_codes differ request");
      if (strcmp(socksinfo->ip, socksreturn->ip) != 0)
	ssh_fatal("ip numbers differ request");
      if (strcmp(socksinfo->port, socksreturn->port) != 0)
	ssh_fatal("port numbers differ request");
      if (strcmp(socksinfo->username, socksreturn->username) != 0)
	ssh_fatal("usernames differ request");
      ssh_socks_free(&socksreturn);
      ssh_socks_free(&socksinfo);
      
      ssh_buffer_clear(&buffer);
      socksinfo = ssh_xmalloc(sizeof(struct SocksInfoRec));
      socksinfo->socks_version_number = 0;
      socksinfo->command_code = (pass % 4) + 90;
      socksinfo->ip =
	ssh_xstrdup(ip_numbers[pass % (sizeof(ip_numbers) /
				   sizeof(ip_numbers[0]))]);
      socksinfo->port =
	ssh_xstrdup(port_numbers[pass % (sizeof(port_numbers) /
				     sizeof(port_numbers[0]))]);
      socksinfo->username =
	ssh_xstrdup(usernames[pass % (sizeof(usernames) /
				  sizeof(usernames[0]))]);
      if (ssh_socks_server_generate_reply(&buffer, socksinfo) !=
	  SSH_SOCKS_SUCCESS)
	ssh_fatal("ssh_socks_server_generate_reply fails");
      if (pass & 1)
	{
	  unsigned char *p;
	  unsigned int len;
	  
	  ssh_buffer_clear(&buffer2);
	  p = ssh_buffer_ptr(&buffer);
	  len = ssh_buffer_len(&buffer);
	  /* Give partial buffer */
	  for(i = 0; i + 1 < len; i++)
	    {
	      ssh_buffer_append(&buffer2, p + i, 1);
	      if (ssh_socks_client_parse_reply(&buffer2, &socksreturn) !=
		  SSH_SOCKS_TRY_AGAIN)
		ssh_fatal("ssh_socks_server_parse_open fails in partial data (should return try_again)");
	    }
	  ssh_buffer_append(&buffer2, p + i, 1);
	  ret = ssh_socks_client_parse_reply(&buffer2, &socksreturn);
	  if (((pass % 4) == 0 && ret != SSH_SOCKS_SUCCESS) ||
	      ((pass % 4) == 1 && ret != SSH_SOCKS_FAILED_REQUEST) ||
	      ((pass % 4) == 2 && ret != SSH_SOCKS_FAILED_IDENTD) ||
	      ((pass % 4) == 3 && ret != SSH_SOCKS_FAILED_USERNAME))
	    ssh_fatal("ssh_socks_client_parse_reply fails for partial data");
          if (ret == SSH_SOCKS_SUCCESS && ssh_buffer_len(&buffer2) != 0)
	    ssh_fatal("Junk left to buffer after server_parse_open");
	}
      else
	{
	  ret = ssh_socks_client_parse_reply(&buffer, &socksreturn);
	  if (((pass % 4) == 0 && ret != SSH_SOCKS_SUCCESS) ||
	      ((pass % 4) == 1 && ret != SSH_SOCKS_FAILED_REQUEST) ||
	      ((pass % 4) == 2 && ret != SSH_SOCKS_FAILED_IDENTD) ||
	      ((pass % 4) == 3 && ret != SSH_SOCKS_FAILED_USERNAME))
	    ssh_fatal("ssh_socks_client_parse_reply fails");
          if (ret == SSH_SOCKS_SUCCESS && ssh_buffer_len(&buffer) != 0)
	    ssh_fatal("Junk left to buffer after server_parse_open");
	}
      if (ret == SSH_SOCKS_SUCCESS)
	{
	  if (socksinfo->socks_version_number !=
	      socksreturn->socks_version_number)
	    ssh_fatal("socks_version_numbers differ reply");
	  if (socksinfo->command_code != socksreturn->command_code)
	    ssh_fatal("command_codes differ reply");
	  if (strcmp(socksinfo->ip, socksreturn->ip) != 0)
	    ssh_fatal("ip numbers differ reply");
	  if (strcmp(socksinfo->port, socksreturn->port) != 0)
	    ssh_fatal("port numbers differ reply");
	  ssh_socks_free(&socksreturn);
	}
      ssh_socks_free(&socksinfo);
    }
  
  ssh_buffer_clear(&buffer);
  
  for(pass = 0;
      pass < (sizeof(ip_invalid_numbers) / sizeof(ip_invalid_numbers[0]));
      pass++)
    {
      socksinfo = ssh_xmalloc(sizeof(struct SocksInfoRec));
      socksinfo->socks_version_number = 4;
      socksinfo->command_code = (pass & 1) + 1;
      socksinfo->ip =
	ssh_xstrdup(ip_invalid_numbers[pass % (sizeof(ip_invalid_numbers) /
					   sizeof(ip_invalid_numbers[0]))]);
      socksinfo->port =
	ssh_xstrdup(port_numbers[pass % (sizeof(port_numbers) /
				     sizeof(port_numbers[0]))]);
      socksinfo->username =
	ssh_xstrdup(usernames[pass % (sizeof(usernames) /
				  sizeof(usernames[0]))]);
      if (ssh_socks_client_generate_open(&buffer, socksinfo) ==
	  SSH_SOCKS_SUCCESS)
	ssh_fatal("ssh_socks_client_generate_open success (should fail, ip)");
      socksinfo->socks_version_number = 0;
      socksinfo->command_code = (pass % 4) + 90;
      if (ssh_socks_server_generate_reply(&buffer, socksinfo) ==
	  SSH_SOCKS_SUCCESS)
	ssh_fatal("ssh_socks_server_generate_reply success (should fail, ip)");
      ssh_socks_free(&socksinfo);
    }
  for(pass = 0;
      pass < (sizeof(port_invalid_numbers) / sizeof(port_invalid_numbers[0]));
      pass++)
    {
      socksinfo = ssh_xmalloc(sizeof(struct SocksInfoRec));
      socksinfo->socks_version_number = 4;
      socksinfo->command_code = (pass & 1) + 1;
      socksinfo->ip =
	ssh_xstrdup(ip_numbers[pass % (sizeof(ip_numbers) /
				   sizeof(ip_numbers[0]))]);
      socksinfo->port =
	ssh_xstrdup(port_invalid_numbers[pass % (sizeof(port_invalid_numbers) /
					     sizeof(port_invalid_numbers[0]))]);
      socksinfo->username =
	ssh_xstrdup(usernames[pass % (sizeof(usernames) /
				  sizeof(usernames[0]))]);
      if (ssh_socks_client_generate_open(&buffer, socksinfo) ==
	  SSH_SOCKS_SUCCESS)
	ssh_fatal("ssh_socks_client_generate_open success (should fail, port)");
      socksinfo->command_code = (pass % 4) + 90;
      socksinfo->socks_version_number = 0;
      if (ssh_socks_server_generate_reply(&buffer, socksinfo) ==
	  SSH_SOCKS_SUCCESS)
	ssh_fatal("ssh_socks_server_generate_reply success (should fail, port)");
      ssh_socks_free(&socksinfo);
    }
  if (ssh_buffer_len(&buffer) != 0)
    ssh_fatal("some of the failed ssh_socks_*_generate_* function wrote something to buffer, size != 0");
  ssh_buffer_uninit(&buffer);
  ssh_buffer_uninit(&buffer2);
  return 0;
}
Exemple #2
0
void tcp_connect_socks_connect_done_cb(SshTcpError error,
                                       SshStream stream,
                                       void *context)
{
    SshFSMThread thread = (SshFSMThread) context;
    ConnectContext c = (ConnectContext) ssh_fsm_get_gdata(thread);
    struct SocksInfoRec socksinfo;
    SocksError ret;
    unsigned char host_port[64], *next = NULL;

    c->handle = NULL;

    if (error != SSH_TCP_OK)
    {
        /* Get next address. */
        if (ssh_ustrchr(c->socks_next_address, ','))
        {
            c->socks_next_address =
                ssh_ustrchr(c->socks_next_address, ',') + 1;
        }
        else
        {   /* At end of list; consider it as a failure. */
            if (tcp_connect_register_failure(thread, error))
            {
                SSH_FSM_CONTINUE_AFTER_CALLBACK(thread);
                return;
            }
            c->socks_next_address = c->socks_addresses;
        }
        /* Try connecting again. */
        SSH_FSM_SET_NEXT(tcp_connect_socks_connect);
        SSH_FSM_CONTINUE_AFTER_CALLBACK(thread);
        return;
    }

    /* Save the stream. */
    c->stream = stream;

    /* Set the callback so that we'll get any required read/write
       notifications. */
    ssh_stream_set_callback(stream, tcp_connect_socks_notify, thread);

    if (c->next_address &&
            (next = ssh_ustrchr(c->next_address, ',')) != NULL)
    {
        *next = '\0';
        next++;
    }

    if (c->socks_type == SSH_TCP_SOCKS5)
    {
        socksinfo.socks_version_number = 5;
        socksinfo.command_code = SSH_SOCKS5_COMMAND_CODE_CONNECT;
        if (c->next_address)
            socksinfo.ip = (unsigned char *) c->next_address;
        else
            socksinfo.ip = c->host_name;
    }
    else
    {
        socksinfo.socks_version_number = 4;
        socksinfo.command_code = SSH_SOCKS4_COMMAND_CODE_CONNECT;
        socksinfo.ip = (unsigned char *) c->next_address;
    }
    ssh_snprintf(host_port, sizeof(host_port), "%d", c->host_port);
    socksinfo.port = host_port;
    socksinfo.username = c->user_name;

    ssh_buffer_clear(c->socks_buf);



    SSH_FSM_SET_NEXT(tcp_connect_socks_send);
    ret = ssh_socks_client_generate_methods(c->socks_buf, &socksinfo);
    if (ret == SSH_SOCKS_SUCCESS)
        ret = ssh_socks_client_generate_open(c->socks_buf, &socksinfo);
    if (ret != SSH_SOCKS_SUCCESS)
    {
        if (next != NULL)
        {
            c->stream = NULL;
            ssh_stream_destroy(stream);
            c->next_address = next;
            SSH_FSM_SET_NEXT(tcp_connect_socks_lookup);
        }
        else
        {
            if (ret == SSH_SOCKS_ERROR_INVALID_ARGUMENT)
                c->error = SSH_TCP_NO_ADDRESS;
            else
                c->error = SSH_TCP_FAILURE;
            SSH_FSM_SET_NEXT(tcp_connect_finish);
        }
    }
    SSH_FSM_CONTINUE_AFTER_CALLBACK(thread);
}