Exemplo n.º 1
0
Arquivo: dns.c Projeto: jpoler/toxic
static void killdns_thread(void *dns_obj)
{
    if (dns_obj)
        tox_dns3_kill(dns_obj);

    memset(&t_data, 0, sizeof(struct thread_data));
    pthread_attr_destroy(&dns_thread.attr);
    pthread_exit(NULL);
}
Exemplo n.º 2
0
QString ToxDNS::queryTox3(const tox3_server& server, const QString &record, bool silent)
{
    QByteArray nameData = record.left(record.indexOf('@')).toUtf8(), id, realRecord;
    QString entry, toxIdStr;
    int toxIdSize, idx, verx, dns_string_len;
    const int dns_string_maxlen = 128;

    void* tox_dns3 = tox_dns3_new(server.pubkey);
    if (!tox_dns3)
    {
        qWarning() << "failed to create a tox_dns3 object for "<<server.name<<", using tox1 as a fallback";
        goto fallbackOnTox1;
    }
    uint32_t request_id;
    uint8_t dns_string[dns_string_maxlen];
    dns_string_len = tox_generate_dns3_string(tox_dns3, dns_string, dns_string_maxlen, &request_id,
                             (uint8_t*)nameData.data(), nameData.size());

    if (dns_string_len < 0) // We can always fallback on tox1 if toxdns3 fails
    {
        qWarning() << "failed to generate dns3 string for "<<server.name<<", using tox1 as a fallback";
        goto fallbackOnTox1;
    }

    realRecord = '_'+QByteArray((char*)dns_string, dns_string_len)+"._tox."+server.name;
    entry = fetchLastTextRecord(realRecord, silent);
    if (entry.isEmpty())
    {
        qWarning() << "Server "<<server.name<<" returned no record, assuming the Tox ID doesn't exist";
        return toxIdStr;
    }

    // Check toxdns protocol version
    verx = entry.indexOf("v=");
    if (verx!=-1)
    {
        verx += 2;
        int verend = entry.indexOf(';', verx);
        if (verend!=-1)
        {
            QString ver = entry.mid(verx, verend-verx);
            if (ver != "tox3")
            {
                qWarning() << "Server "<<server.name<<" returned a bad version ("<<ver<<"), using tox1 as a fallback";
                goto fallbackOnTox1;
            }
        }
    }

    // Get and decrypt the tox id
    idx = entry.indexOf("id=");
    if (idx < 0)
    {
        qWarning() << "Server "<<server.name<<" returned an empty id, using tox1 as a fallback";
        goto fallbackOnTox1;
    }

    idx += 3;
    id = entry.mid(idx).toUtf8();
    uint8_t toxId[TOX_ADDRESS_SIZE];
    toxIdSize = tox_decrypt_dns3_TXT(tox_dns3, toxId, (uint8_t*)id.data(), id.size(), request_id);
    if (toxIdSize < 0) // We can always fallback on tox1 if toxdns3 fails
    {
        qWarning() << "Failed to decrypt dns3 reply for "<<server.name<<", using tox1 as a fallback";
        goto fallbackOnTox1;
    }

    tox_dns3_kill(tox_dns3);
    toxIdStr = CFriendAddress::toString(toxId);
    return toxIdStr;

    // Centralized error handling, fallback on tox1 queries
fallbackOnTox1:
    if (tox_dns3)
        tox_dns3_kill(tox_dns3);

#if TOX1_SILENT_FALLBACK
    toxIdStr = queryTox1(record, silent);
#elif TOX1_ASK_FALLBACK
    QMessageBox::StandardButton btn =
        QMessageBox::warning(nullptr, "qTox",
                             tr("It appears that qTox has to use the old protocol to access DNS record of your friend's Tox ID.\n"
                                "Unfortunately tox1 is not secure, and you are at risk of someone hijacking what is sent between you and ToxDNS service.\n"
                                "Should tox1 be used anyway?\n"
                                "If unsure, press 'No', so that request to ToxDNS service will not be made using unsecure protocol."),
                                QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
    if (btn == QMessageBox::Yes)
        queryTox1(record, silent);

#endif
    return toxIdStr;
}
Exemplo n.º 3
0
void CToxProto::SearchByNameAsync(void *arg)
{
	char *query = (char*)arg;
	char *name = strtok(query, "@");
	char *domain = strtok(NULL, "");

	int resolved = 0;

	if (IsFileExists((TCHAR*)VARST(_T(TOX_INI_PATH))))
	{
		char fileName[MAX_PATH];
		mir_strcpy(fileName, VARS(TOX_INI_PATH));

		char *section, sections[MAX_PATH], value[TOX_PUBLIC_KEY_SIZE * 2];
		GetPrivateProfileSectionNamesA(sections, _countof(sections), fileName);
		section = sections;
		while (*section != NULL)
		{
			if (strstr(section, "Dns_") == section)
			{
				GetPrivateProfileStringA(section, "Domain", NULL, value, _countof(value), fileName);
				ptrA dnsDomain(mir_strdup(value));
				GetPrivateProfileStringA(section, "PubKey", NULL, value, _countof(value), fileName);
				ToxBinAddress dnsPubKey = value;

				if (domain == NULL || mir_strcmpi(domain, dnsDomain) == 0)
				{
					void *dns = tox_dns3_new((uint8_t*)(const uint8_t*)dnsPubKey);

					uint32_t requestId = 0;
					uint8_t dnsString[MAX_PATH];
					size_t length = tox_generate_dns3_string(dns, dnsString, sizeof(dnsString), &requestId, (uint8_t*)CharLowerA(name), (uint8_t)mir_strlen(name));
					if (length != TOX_ERROR)
					{
						dnsString[length] = 0;
						char dnsQuery[MAX_PATH * 2];
						mir_snprintf(dnsQuery, "_%s._tox.%s", dnsString, dnsDomain);

						ToxHexAddress address = ResolveToxAddressFromDns(dnsQuery);
						if (!address.IsEmpty())
						{
							PROTOSEARCHRESULT psr = { sizeof(PROTOSEARCHRESULT) };
							psr.flags = PSR_UTF8;
							psr.id.a = mir_strdup(address);
							psr.nick.a = mir_strdup(name);

							char email[MAX_PATH];
							mir_snprintf(email, "%s@%s", name, domain);
							psr.email.a = mir_strdup(email);

							ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)1, (LPARAM)&psr);
							break;
						}
					}
					tox_dns3_kill(dns);
				}
			}
			section += mir_strlen(section) + 1;
		}
	}

	if (resolved == 0 && domain)
	{
		char dnsQuery[MAX_PATH];
		mir_snprintf(dnsQuery, "%s._tox.%s", name, domain);

		ToxHexAddress address = ResolveToxAddressFromDns(dnsQuery);
		if (!address.IsEmpty())
		{
			PROTOSEARCHRESULT psr = { sizeof(PROTOSEARCHRESULT) };
			psr.flags = PSR_UTF8;
			psr.id.a = mir_strdup(address);
			psr.nick.a = mir_strdup(name);

			char email[MAX_PATH];
			mir_snprintf(email, "%s@%s", name, domain);
			psr.email.a = mir_strdup(email);

			ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)1, (LPARAM)&psr);
		}
	}

	ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)1, 0);
	mir_free(arg);
}