mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Start implementing toxme.se support
This commit is contained in:
parent
5dce927292
commit
217ca20085
|
@ -32,6 +32,8 @@
|
||||||
|
|
||||||
#include <sodium.h>
|
#include <sodium.h>
|
||||||
|
|
||||||
|
#include "toxme.h"
|
||||||
|
|
||||||
#ifdef LOG_TO_FILE
|
#ifdef LOG_TO_FILE
|
||||||
static QtMessageHandler dflt;
|
static QtMessageHandler dflt;
|
||||||
static QTextStream* logFile {nullptr};
|
static QTextStream* logFile {nullptr};
|
||||||
|
@ -183,6 +185,10 @@ int main(int argc, char *argv[])
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Run
|
// Run
|
||||||
|
Toxme::lookup("tux3@toxme.se");
|
||||||
|
Toxme::createAddress(ToxID::fromString("95B6B3A34C82FC449D1F1CA9A7F621DE6A7516D0AA1183E128A5467590BD8913B8C5D287D924"),
|
||||||
|
"testToxmeAPI@toxme.se",false,"This is a test");
|
||||||
|
|
||||||
a.setQuitOnLastWindowClosed(false);
|
a.setQuitOnLastWindowClosed(false);
|
||||||
int errorcode = a.exec();
|
int errorcode = a.exec();
|
||||||
|
|
||||||
|
|
131
src/toxme.cpp
Normal file
131
src/toxme.cpp
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
#include "toxme.h"
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <sodium/crypto_box.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
const QString Toxme::apiUrl{"https://toxme.se/api"};
|
||||||
|
|
||||||
|
void Toxme::incrementNonce(unsigned char nonce[])
|
||||||
|
{
|
||||||
|
auto nonceSize = crypto_box_NONCEBYTES;
|
||||||
|
for (decltype(nonceSize) i=0; i<nonceSize; ++i)
|
||||||
|
{
|
||||||
|
if (nonce[i]==0xFFU)
|
||||||
|
{
|
||||||
|
if (i==nonceSize-1)
|
||||||
|
{
|
||||||
|
// Shouldn't matter, since we don't reuse keys
|
||||||
|
// But still gets a warning because that's exceedingly unlikely to happen
|
||||||
|
qWarning() << "Toxme::incrementNonce: Nonce overflow!";
|
||||||
|
memset(nonce,0,nonceSize);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nonce[i]=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nonce[i]++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray Toxme::makeJsonRequest(QString json)
|
||||||
|
{
|
||||||
|
QNetworkAccessManager netman;
|
||||||
|
QNetworkRequest request{apiUrl};
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||||
|
|
||||||
|
QNetworkReply* reply = netman.post(request,json.toUtf8());
|
||||||
|
while (!reply->isFinished())
|
||||||
|
qApp->processEvents();
|
||||||
|
|
||||||
|
return reply->readAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray Toxme::prepareEncryptedJson(int action, QString payload)
|
||||||
|
{
|
||||||
|
static unsigned char nonce[crypto_box_NONCEBYTES]={0};
|
||||||
|
|
||||||
|
unsigned char pk[crypto_box_PUBLICKEYBYTES];
|
||||||
|
unsigned char sk[crypto_box_SECRETKEYBYTES];
|
||||||
|
crypto_box_keypair(pk,sk);
|
||||||
|
|
||||||
|
QByteArray payloadData = payload.toUtf8();
|
||||||
|
const size_t mlen = crypto_box_ZEROBYTES+payloadData.size();
|
||||||
|
unsigned char* payloadMsg = new unsigned char[mlen];
|
||||||
|
unsigned char* payloadEnc = new unsigned char[mlen];
|
||||||
|
memcpy(payloadMsg+crypto_box_ZEROBYTES,payloadData.data(),payloadData.size());
|
||||||
|
|
||||||
|
crypto_box(payloadEnc,payloadMsg,mlen,nonce,pk,sk);
|
||||||
|
QByteArray payloadEncData(reinterpret_cast<char*>(payloadEnc), mlen);
|
||||||
|
delete[] payloadMsg;
|
||||||
|
delete[] payloadEnc;
|
||||||
|
|
||||||
|
const QString json{"{\"action\":"+QString().setNum(action)+","
|
||||||
|
"\"public_key\":\""+QByteArray(reinterpret_cast<char*>(pk),
|
||||||
|
crypto_box_PUBLICKEYBYTES)+"\","
|
||||||
|
"\"encrypted\":\""+payloadEncData+"\","
|
||||||
|
"\"nonce\":\""+QByteArray(reinterpret_cast<char*>(nonce),
|
||||||
|
crypto_box_NONCEBYTES)+"\"}"};
|
||||||
|
incrementNonce(nonce);
|
||||||
|
return json.toUtf8();
|
||||||
|
}
|
||||||
|
|
||||||
|
ToxID Toxme::lookup(QString address)
|
||||||
|
{
|
||||||
|
// JSON injection ?
|
||||||
|
address.replace('\\',"\\\\");
|
||||||
|
address.replace('"',"\"");
|
||||||
|
|
||||||
|
ToxID id;
|
||||||
|
const QString json{"{\"action\":3,\"name\":\""+address+"\"}"};
|
||||||
|
static const QByteArray pattern{"public_key\""};
|
||||||
|
|
||||||
|
QByteArray response = makeJsonRequest(json);
|
||||||
|
const int index = response.indexOf(pattern);
|
||||||
|
if (index == -1)
|
||||||
|
return id;
|
||||||
|
response = response.mid(index+pattern.size());
|
||||||
|
|
||||||
|
const int idStart = response.indexOf('"');
|
||||||
|
if (idStart == -1)
|
||||||
|
return id;
|
||||||
|
response = response.mid(idStart+1);
|
||||||
|
|
||||||
|
const int idEnd = response.indexOf('"');
|
||||||
|
if (idEnd == -1)
|
||||||
|
return id;
|
||||||
|
response.truncate(idEnd);
|
||||||
|
|
||||||
|
id = ToxID::fromString(response);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Toxme::createAddress(ToxID id, QString address,
|
||||||
|
bool keepPrivate, QString bio)
|
||||||
|
{
|
||||||
|
int privacy = keepPrivate ? 0 : 2;
|
||||||
|
// JSON injection ?
|
||||||
|
bio.replace('\\',"\\\\");
|
||||||
|
bio.replace('"',"\"");
|
||||||
|
address.replace('\\',"\\\\");
|
||||||
|
address.replace('"',"\"");
|
||||||
|
|
||||||
|
const QString payload{"{\"tox_id\":\""+id.toString()+"\","
|
||||||
|
"\"name\":\""+address+"\","
|
||||||
|
"\"privacy\":"+QString().setNum(privacy)+","
|
||||||
|
"\"bio\":\""+bio+"\","
|
||||||
|
"\"timestamp\":"+QString().setNum(time(0))+"}"};
|
||||||
|
|
||||||
|
QByteArray response = makeJsonRequest(prepareEncryptedJson(1,payload));
|
||||||
|
qDebug() << "payload:"<<payload;
|
||||||
|
qDebug() << "response:"<<response;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
34
src/toxme.h
Normal file
34
src/toxme.h
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef TOXME_H
|
||||||
|
#define TOXME_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QMutex>
|
||||||
|
#include "corestructs.h"
|
||||||
|
|
||||||
|
class QNetworkAccessManager;
|
||||||
|
|
||||||
|
/// This class implements a client for the toxme.se API
|
||||||
|
/// The class is thread safe
|
||||||
|
/// May process events while waiting for blocking calls
|
||||||
|
class Toxme
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Converts a toxme.se address to a Tox ID, returns an empty ID on error
|
||||||
|
static ToxID lookup(QString address);
|
||||||
|
/// Creates a new toxme.se address associated with a Tox ID.
|
||||||
|
/// If keepPrivate, the address will not be published on toxme.se
|
||||||
|
/// The bio is a short optional description of yourself if you want to publish your address.
|
||||||
|
static bool createAddress(ToxID id, QString address,
|
||||||
|
bool keepPrivate=true, QString bio=QString());
|
||||||
|
|
||||||
|
private:
|
||||||
|
Toxme()=delete;
|
||||||
|
static QByteArray makeJsonRequest(QString json);
|
||||||
|
static QByteArray prepareEncryptedJson(int action, QString payload);
|
||||||
|
static void incrementNonce(unsigned char nonce[]);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const QString apiUrl;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TOXME_H
|
Loading…
Reference in New Issue
Block a user