Exemple #1
0
  DNS::HostMap DNS::resolve( const std::string& service, const std::string& proto,
                             const std::string& domain, const LogSink& logInstance )
  {
    const std::string dname = "_" +  service + "._" + proto + "." + domain;
    bool error = false;

    DNS::HostMap servers;
    DNS_RECORD* pRecord;
    if( DnsQuery( dname.c_str(), DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &pRecord, NULL ) == ERROR_SUCCESS )
    {
      DNS_RECORD* pRec = pRecord;
      do
      {
        if( pRec->wType == DNS_TYPE_SRV )
        {
          servers[pRec->Data.SRV.pNameTarget] = pRec->Data.SRV.wPort;
        }
        pRec = pRec->pNext;
      }
      while( pRec != NULL );
      DnsRecordListFree( pRecord, DnsFreeRecordList );
    }
    else
      error = true;

    if( error || !servers.size() )
    {
      servers = defaultHostMap( domain, logInstance );
    }

    return servers;
  }
  void ConnectionSOCKS5Proxy::handleConnect( const ConnectionBase* /*connection*/ )
  {
    if( m_connection )
    {
      std::string server = m_server;
      int port = m_port;
      if( port == -1 )
      {
        DNS::HostMap servers = DNS::resolve( m_server, m_logInstance );
        if( servers.size() )
        {
          server = (*(servers.begin())).first;
          port = (*(servers.begin())).second;
        }
      }
      m_logInstance.log( LogLevelDebug, LogAreaClassConnectionSOCKS5Proxy,
                         "attempting to negotiate socks5 proxy connection" );

      bool auth = !m_proxyUser.empty() && !m_proxyPassword.empty();
      char *d = new char[auth ? 4 : 3];
      d[0] = 0x05; // SOCKS version 5
      if( auth )
      {
        d[1] = 0x02; // two methods
        d[3] = 0x02; // method: username/password auth
      }
      else
        d[1] = 0x01; // one method
      d[2] = 0x00; // method: no auth

      if( !send( std::string( d, auth ? 4 : 3 ) ) )
      {
        cleanup();
        if( m_handler )
          m_handler->handleDisconnect( this, ConnIoError );
      }
      delete[] d;
    }
  }
  DNS::HostMap DNS::resolve( const std::string& service, const std::string& proto,
                             const std::string& domain, const LogSink& logInstance )
  {
    const std::string dname = "_" +  service + "._" + proto + "." + domain;
    bool error = false;

    DNS::HostMap servers;
    DNS_RECORD* pRecord = NULL;
    DNS_STATUS status = DnsQuery_UTF8( dname.c_str(), DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &pRecord, NULL );
    if( status == ERROR_SUCCESS )
    {
      // NOTE: DnsQuery_UTF8 and DnsQuery_A really should have been defined with
      // PDNS_RECORDA instead of PDNS_RECORD, since that's what it is (even with _UNICODE defined).
      // We'll correct for that mistake with a cast.
      DNS_RECORDA* pRec = (DNS_RECORDA*)pRecord;
      do
      {
        if( pRec->wType == DNS_TYPE_SRV )
        {
          servers[pRec->Data.SRV.pNameTarget] = pRec->Data.SRV.wPort;
        }
        pRec = pRec->pNext;
      }
      while( pRec != NULL );
      DnsRecordListFree( pRecord, DnsFreeRecordList );
    }
    else
    {
      logInstance.warn( LogAreaClassDns, "DnsQuery_UTF8() failed: " + util::int2string( status ) );
      error = true;
    }

    if( error || !servers.size() )
    {
      servers = defaultHostMap( domain, logInstance );
    }

    return servers;
  }
void jConnection::loadSettings()
{
	if(m_state != StateDisconnected)
	{
		DEBUG("Try to load settings in %d state", (int)m_state);
		return;
	}
	DEBUG() << Q_FUNC_INFO;
    loadProxySettings();
    m_hosts.clear();
    QSettings settings(QSettings::defaultFormat(), QSettings::UserScope, "qutim/qutim."+m_profile_name+"/jabber."+m_account_name, "accountsettings");

    settings.beginGroup("main");
	JID jid(utils::toStd(m_account_name));

    QString server = utils::fromStd(jid.server());
    int port = settings.value("port",5222).toInt();
    m_use_dns_srv = settings.value("usedns", true).toBool();
    TLSPolicy tls_policy = TLSOptional;
    if(server=="qutim.org")
    {
		server="jabber.qutim.org";
		port = 5222;
		m_use_dns_srv = false;
    }
    bool use_sasl = settings.value("usesasl", true).toBool();
    bool compress = settings.value("compress", true).toBool();
    server = settings.value("server",server).toString();
    m_server = utils::toStd(server);
    m_port = port;
    if(!m_use_dns_srv)
    {
		if(port==-1)
			port = 5222;
		m_hosts << qMakePair( server, port );
    }
    else
	{
		static LogSink logsink;
		DNS::HostMap hosts = DNS::resolve(m_server, logsink);
		DNS::HostMap::iterator h = hosts.begin();
		for(;h!=hosts.end();h++)
		{
			QPair<QString, int> host( utils::fromStd(h->first), h->second );
			static const QRegExp valid_hostname( "(\\w+\\.)+\\w+" );
			Q_ASSERT_X(valid_hostname.isValid(),"jConnection::loadSettings()","Regexp is not valid");
			if( valid_hostname.exactMatch( host.first ) || !QHostAddress( host.first ).isNull() )
				m_hosts.append(host);
		}
		if( m_hosts.isEmpty() )
			m_hosts << qMakePair( server, 5222 );
    }
    switch(settings.value("tlspolicy",1).toInt())
    {
	case 0:
	    tls_policy = TLSDisabled;
	    break;
	case 1:
	    tls_policy = TLSOptional;
	    break;
	case 2:
	    tls_policy = TLSRequired;
	    break;
    }
	settings.endGroup();

	ClientBase *jClient = dynamic_cast<ClientBase*>(m_handler);
	if(!jClient)
	{
		DEBUG("Try to load settings, but handler is not ClientBase. Error os %d", (int)m_error);
		m_handler->handleDisconnect(this, m_error);
		if(!(jClient = dynamic_cast<ClientBase*>(m_handler)))
		{
			DEBUG("Try lo load settings, but handle disconnect go wrong");
			return;
		}
	}

    jClient->setTls(tls_policy);
    jClient->setSasl(use_sasl);
	jClient->setCompression(compress);
}
  void ConnectionSOCKS5Proxy::negotiate()
  {
    m_s5state = S5StateNegotiating;
    char *d = new char[m_ip ? 10 : 6 + m_server.length() + 1];
    int pos = 0;
    d[pos++] = 0x05; // SOCKS version 5
    d[pos++] = 0x01; // command CONNECT
    d[pos++] = 0x00; // reserved
    int port = m_port;
    std::string server = m_server;
    if( m_ip ) // IP address
    {
      d[pos++] = 0x01; // IPv4 address
      std::string s;
      int j = server.length();
      int l = 0;
      for( int k = 0; k < j && l < 4; ++k )
      {
        if( server[k] != '.' )
          s += server[k];

        if( server[k] == '.' || k == j-1 )
        {
          d[pos++] = atoi( s.c_str() ) & 0x0FF;
          s = "";
          ++l;
        }
      }
    }
    else // hostname
    {
      if( port == -1 )
      {
        DNS::HostMap servers = DNS::resolve( m_server, m_logInstance );
        if( servers.size() )
        {
          server = (*(servers.begin())).first;
          port = (*(servers.begin())).second;
        }
      }
      d[pos++] = 0x03; // hostname
      d[pos++] = m_server.length();
      strncpy( d + pos, m_server.c_str(), m_server.length() );
      pos += m_server.length();
    }
    int nport = htons( port );
    d[pos++] = nport;
    d[pos++] = nport >> 8;

#ifndef _WIN32_WCE
    std::ostringstream oss;
    oss << "requesting socks5 proxy connection to " << server << ":" << port;
    m_logInstance.log( LogLevelDebug, LogAreaClassConnectionSOCKS5Proxy, oss.str() );
#endif

    if( !send( std::string( d, pos ) ) )
    {
      cleanup();
      m_handler->handleDisconnect( this, ConnIoError );
    }
    delete[] d;
  }