Wormhole connection
This commit is contained in:
@@ -2,11 +2,13 @@
|
|||||||
|
|
||||||
Logger::Logger(QObject *parent, QString fileName) : QObject(parent) {
|
Logger::Logger(QObject *parent, QString fileName) : QObject(parent) {
|
||||||
m_showDate = true;
|
m_showDate = true;
|
||||||
|
|
||||||
if (!fileName.isEmpty()) {
|
if (!fileName.isEmpty()) {
|
||||||
file = new QFile;
|
file = new QFile;
|
||||||
file->setFileName(fileName);
|
file->setFileName(fileName);
|
||||||
file->open(QIODevice::Append | QIODevice::Text);
|
file->open(QIODevice::Append | QIODevice::Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
write("=========Startup==========");
|
write("=========Startup==========");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14,7 +16,7 @@ void Logger::write(const QString &value) {
|
|||||||
if (!file)
|
if (!file)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QString text = value;// + "";
|
QString text = value;
|
||||||
text = QDateTime::currentDateTime().toString("dd.MM.yyyy hh:mm:ss ") + text;
|
text = QDateTime::currentDateTime().toString("dd.MM.yyyy hh:mm:ss ") + text;
|
||||||
QTextStream out(file);
|
QTextStream out(file);
|
||||||
out.setCodec("UTF-8");
|
out.setCodec("UTF-8");
|
||||||
|
|||||||
@@ -109,7 +109,17 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::createWebsocket() {
|
void MainWindow::createWebsocket() {
|
||||||
|
// Create the websocket server, for listening to direct connections
|
||||||
wsserver = new WSServer(8237, false, this);
|
wsserver = new WSServer(8237, false, this);
|
||||||
|
|
||||||
|
// Connect to the wormhole service
|
||||||
|
wormhole = new WormholeClient(this, AppDataServer::getInstance()->getWormholeCode(
|
||||||
|
AppDataServer::getInstance()->getSecretHex()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::replaceWormholeClient(WormholeClient* newClient) {
|
||||||
|
delete wormhole;
|
||||||
|
wormhole = newClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::restoreSavedStates() {
|
void MainWindow::restoreSavedStates() {
|
||||||
@@ -1367,4 +1377,5 @@ MainWindow::~MainWindow()
|
|||||||
delete logger;
|
delete logger;
|
||||||
|
|
||||||
delete wsserver;
|
delete wsserver;
|
||||||
|
delete wormhole;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
class RPC;
|
class RPC;
|
||||||
class Settings;
|
class Settings;
|
||||||
class WSServer;
|
class WSServer;
|
||||||
|
class WormholeClient;
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
@@ -44,6 +45,8 @@ public:
|
|||||||
QString doSendTxValidations(Tx tx);
|
QString doSendTxValidations(Tx tx);
|
||||||
void setDefaultPayFrom();
|
void setDefaultPayFrom();
|
||||||
|
|
||||||
|
void replaceWormholeClient(WormholeClient* newClient);
|
||||||
|
|
||||||
Ui::MainWindow* ui;
|
Ui::MainWindow* ui;
|
||||||
|
|
||||||
QLabel* statusLabel;
|
QLabel* statusLabel;
|
||||||
@@ -106,7 +109,8 @@ private:
|
|||||||
|
|
||||||
void createWebsocket();
|
void createWebsocket();
|
||||||
|
|
||||||
WSServer* wsserver = nullptr;
|
WSServer* wsserver = nullptr;
|
||||||
|
WormholeClient* wormhole = nullptr;
|
||||||
|
|
||||||
RPC* rpc = nullptr;
|
RPC* rpc = nullptr;
|
||||||
QCompleter* labelCompleter = nullptr;
|
QCompleter* labelCompleter = nullptr;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ WSServer::WSServer(quint16 port, bool debug, QObject *parent) :
|
|||||||
m_debug(debug)
|
m_debug(debug)
|
||||||
{
|
{
|
||||||
m_mainWindow = (MainWindow *) parent;
|
m_mainWindow = (MainWindow *) parent;
|
||||||
if (m_pWebSocketServer->listen(QHostAddress::AnyIPv4, port)) {
|
if (m_pWebSocketServer->listen(QHostAddress::AnyIPv4, port+100)) {
|
||||||
if (m_debug)
|
if (m_debug)
|
||||||
qDebug() << "Echoserver listening on port" << port;
|
qDebug() << "Echoserver listening on port" << port;
|
||||||
connect(m_pWebSocketServer, &QWebSocketServer::newConnection,
|
connect(m_pWebSocketServer, &QWebSocketServer::newConnection,
|
||||||
@@ -69,6 +69,49 @@ void WSServer::socketDisconnected()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===============================
|
||||||
|
// WormholeClient
|
||||||
|
//===============================
|
||||||
|
WormholeClient::WormholeClient(MainWindow* p, QString wormholeCode) {
|
||||||
|
this->parent = p;
|
||||||
|
this->code = wormholeCode;
|
||||||
|
connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
WormholeClient::~WormholeClient() {
|
||||||
|
if (m_webSocket.isValid()) {
|
||||||
|
m_webSocket.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WormholeClient::connect() {
|
||||||
|
QObject::connect(&m_webSocket, &QWebSocket::connected, this, &WormholeClient::onConnected);
|
||||||
|
QObject::connect(&m_webSocket, &QWebSocket::disconnected, this, &WormholeClient::closed);
|
||||||
|
|
||||||
|
m_webSocket.open(QUrl("ws://127.0.0.1:7070"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WormholeClient::onConnected()
|
||||||
|
{
|
||||||
|
qDebug() << "WebSocket connected";
|
||||||
|
QObject::connect(&m_webSocket, &QWebSocket::textMessageReceived,
|
||||||
|
this, &WormholeClient::onTextMessageReceived);
|
||||||
|
|
||||||
|
auto payload = QJsonDocument( QJsonObject {
|
||||||
|
{"register", code}
|
||||||
|
}).toJson();
|
||||||
|
|
||||||
|
m_webSocket.sendTextMessage(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WormholeClient::onTextMessageReceived(QString message)
|
||||||
|
{
|
||||||
|
qDebug() << "Message received:" << message;
|
||||||
|
AppDataServer::getInstance()->processMessage(message, parent, &m_webSocket);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ==============================
|
// ==============================
|
||||||
// AppDataServer
|
// AppDataServer
|
||||||
// ==============================
|
// ==============================
|
||||||
@@ -80,6 +123,30 @@ QString AppDataServer::getSecretHex() {
|
|||||||
return s.value("mobileapp/secret", "").toString();
|
return s.value("mobileapp/secret", "").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString AppDataServer::getWormholeCode(QString secretHex) {
|
||||||
|
unsigned char* secret = new unsigned char[crypto_secretbox_KEYBYTES];
|
||||||
|
sodium_hex2bin(secret, crypto_secretbox_KEYBYTES, secretHex.toStdString().c_str(), crypto_secretbox_KEYBYTES*2,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
|
||||||
|
unsigned char* out1 = new unsigned char[crypto_hash_sha256_BYTES];
|
||||||
|
crypto_hash_sha256(out1, secret, crypto_secretbox_KEYBYTES);
|
||||||
|
|
||||||
|
unsigned char* out2 = new unsigned char[crypto_hash_sha256_BYTES];
|
||||||
|
crypto_hash_sha256(out2, out1, crypto_hash_sha256_BYTES);
|
||||||
|
|
||||||
|
char* wmcode = new char[crypto_hash_sha256_BYTES*2 + 1];
|
||||||
|
sodium_bin2hex(wmcode, crypto_hash_sha256_BYTES*2 + 1, out2, crypto_hash_sha256_BYTES);
|
||||||
|
|
||||||
|
QString wmcodehex(wmcode);
|
||||||
|
|
||||||
|
delete[] wmcode;
|
||||||
|
delete[] out2;
|
||||||
|
delete[] out1;
|
||||||
|
delete[] secret;
|
||||||
|
|
||||||
|
return wmcodehex;
|
||||||
|
}
|
||||||
|
|
||||||
void AppDataServer::saveNewSecret(QString secretHex) {
|
void AppDataServer::saveNewSecret(QString secretHex) {
|
||||||
QSettings s;
|
QSettings s;
|
||||||
s.setValue("mobileapp/secret", secretHex);
|
s.setValue("mobileapp/secret", secretHex);
|
||||||
@@ -87,13 +154,13 @@ void AppDataServer::saveNewSecret(QString secretHex) {
|
|||||||
s.sync();
|
s.sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppDataServer::connectAppDialog(QWidget* parent) {
|
void AppDataServer::connectAppDialog(MainWindow* parent) {
|
||||||
QDialog d(parent);
|
QDialog d(parent);
|
||||||
ui = new Ui_MobileAppConnector();
|
ui = new Ui_MobileAppConnector();
|
||||||
ui->setupUi(&d);
|
ui->setupUi(&d);
|
||||||
Settings::saveRestore(&d);
|
Settings::saveRestore(&d);
|
||||||
|
|
||||||
updateUIWithNewQRCode();
|
updateUIWithNewQRCode(parent);
|
||||||
updateConnectedUI();
|
updateConnectedUI();
|
||||||
|
|
||||||
QObject::connect(ui->btnDisconnect, &QPushButton::clicked, [=] () {
|
QObject::connect(ui->btnDisconnect, &QPushButton::clicked, [=] () {
|
||||||
@@ -108,11 +175,12 @@ void AppDataServer::connectAppDialog(QWidget* parent) {
|
|||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
tempSecret = "";
|
tempSecret = "";
|
||||||
|
delete tempWormholeClient;
|
||||||
delete ui;
|
delete ui;
|
||||||
ui = nullptr;
|
ui = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppDataServer::updateUIWithNewQRCode() {
|
void AppDataServer::updateUIWithNewQRCode(MainWindow* mainwindow) {
|
||||||
// Get the address of the localhost
|
// Get the address of the localhost
|
||||||
auto addrList = QNetworkInterface::allAddresses();
|
auto addrList = QNetworkInterface::allAddresses();
|
||||||
|
|
||||||
@@ -138,7 +206,7 @@ void AppDataServer::updateUIWithNewQRCode() {
|
|||||||
sodium_bin2hex(secretHex, crypto_secretbox_KEYBYTES*2+1, secretBin, crypto_secretbox_KEYBYTES);
|
sodium_bin2hex(secretHex, crypto_secretbox_KEYBYTES*2+1, secretBin, crypto_secretbox_KEYBYTES);
|
||||||
|
|
||||||
QString secretStr(secretHex);
|
QString secretStr(secretHex);
|
||||||
tempSecret = secretStr;
|
registerNewTempSecret(secretStr, mainwindow);
|
||||||
|
|
||||||
QString codeStr = uri + "," + secretStr;
|
QString codeStr = uri + "," + secretStr;
|
||||||
|
|
||||||
@@ -146,6 +214,12 @@ void AppDataServer::updateUIWithNewQRCode() {
|
|||||||
ui->txtConnStr->setText(codeStr);
|
ui->txtConnStr->setText(codeStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AppDataServer::registerNewTempSecret(QString tmpSecretHex, MainWindow* main) {
|
||||||
|
tempSecret = tmpSecretHex;
|
||||||
|
|
||||||
|
tempWormholeClient = new WormholeClient(main, getWormholeCode(tempSecret));
|
||||||
|
}
|
||||||
|
|
||||||
void AppDataServer::updateConnectedUI() {
|
void AppDataServer::updateConnectedUI() {
|
||||||
if (ui == nullptr)
|
if (ui == nullptr)
|
||||||
return;
|
return;
|
||||||
@@ -222,7 +296,8 @@ QString AppDataServer::encryptOutgoing(QString msg) {
|
|||||||
|
|
||||||
auto json = QJsonDocument(QJsonObject{
|
auto json = QJsonDocument(QJsonObject{
|
||||||
{"nonce", QString(newLocalNonce)},
|
{"nonce", QString(newLocalNonce)},
|
||||||
{"payload", QString(encryptedHex)}
|
{"payload", QString(encryptedHex)},
|
||||||
|
{"to", getWormholeCode(getSecretHex())}
|
||||||
});
|
});
|
||||||
|
|
||||||
delete[] noncebin;
|
delete[] noncebin;
|
||||||
@@ -345,13 +420,17 @@ void AppDataServer::processMessage(QString message, MainWindow* mainWindow, QWeb
|
|||||||
// decryptMessage()
|
// decryptMessage()
|
||||||
saveNewSecret(tempSecret);
|
saveNewSecret(tempSecret);
|
||||||
|
|
||||||
|
// Swap out the wormhole connection
|
||||||
|
mainWindow->replaceWormholeClient(tempWormholeClient);
|
||||||
|
tempWormholeClient = nullptr;
|
||||||
|
|
||||||
// If the Connection UI is showing, we have to update the UI as well
|
// If the Connection UI is showing, we have to update the UI as well
|
||||||
if (ui != nullptr) {
|
if (ui != nullptr) {
|
||||||
// Update the connected phone information
|
// Update the connected phone information
|
||||||
updateConnectedUI();
|
updateConnectedUI();
|
||||||
|
|
||||||
// Update with a new QR Code for safety, so this secret isn't used by anyone else
|
// Update with a new QR Code for safety, so this secret isn't used by anyone else
|
||||||
updateUIWithNewQRCode();
|
updateUIWithNewQRCode(mainWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
processDecryptedMessage(decrypted, mainWindow, pClient);
|
processDecryptedMessage(decrypted, mainWindow, pClient);
|
||||||
|
|||||||
@@ -33,6 +33,28 @@ private:
|
|||||||
bool m_debug;
|
bool m_debug;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class WormholeClient : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void closed();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void onConnected();
|
||||||
|
void onTextMessageReceived(QString message);
|
||||||
|
|
||||||
|
public:
|
||||||
|
WormholeClient(MainWindow* parent, QString wormholeCode);
|
||||||
|
~WormholeClient();
|
||||||
|
|
||||||
|
void connect();
|
||||||
|
|
||||||
|
private:
|
||||||
|
MainWindow* parent = nullptr;
|
||||||
|
QWebSocket m_webSocket;
|
||||||
|
QString code;
|
||||||
|
};
|
||||||
|
|
||||||
enum NonceType {
|
enum NonceType {
|
||||||
LOCAL = 1,
|
LOCAL = 1,
|
||||||
REMOTE
|
REMOTE
|
||||||
@@ -47,9 +69,9 @@ public:
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void connectAppDialog(QWidget* parent);
|
void connectAppDialog(MainWindow* parent);
|
||||||
void updateConnectedUI();
|
void updateConnectedUI();
|
||||||
void updateUIWithNewQRCode();
|
void updateUIWithNewQRCode(MainWindow* mainwindow);
|
||||||
|
|
||||||
void processSendTx(QJsonObject sendTx, MainWindow* mainwindow, QWebSocket* pClient);
|
void processSendTx(QJsonObject sendTx, MainWindow* mainwindow, QWebSocket* pClient);
|
||||||
void processMessage(QString message, MainWindow* mainWindow, QWebSocket* pClient);
|
void processMessage(QString message, MainWindow* mainWindow, QWebSocket* pClient);
|
||||||
@@ -60,9 +82,12 @@ public:
|
|||||||
QString decryptMessage(QJsonDocument msg, QString secretHex, QString lastRemoteNonceHex);
|
QString decryptMessage(QJsonDocument msg, QString secretHex, QString lastRemoteNonceHex);
|
||||||
QString encryptOutgoing(QString msg);
|
QString encryptOutgoing(QString msg);
|
||||||
|
|
||||||
|
QString getWormholeCode(QString secretHex);
|
||||||
QString getSecretHex();
|
QString getSecretHex();
|
||||||
void saveNewSecret(QString secretHex);
|
void saveNewSecret(QString secretHex);
|
||||||
|
|
||||||
|
void registerNewTempSecret(QString tmpSecretHex, MainWindow* main);
|
||||||
|
|
||||||
QString getNonceHex(NonceType nt);
|
QString getNonceHex(NonceType nt);
|
||||||
void saveNonceHex(NonceType nt, QString noncehex);
|
void saveNonceHex(NonceType nt, QString noncehex);
|
||||||
|
|
||||||
@@ -70,8 +95,10 @@ private:
|
|||||||
AppDataServer() = default;
|
AppDataServer() = default;
|
||||||
|
|
||||||
static AppDataServer* instance;
|
static AppDataServer* instance;
|
||||||
QString tempSecret;
|
|
||||||
Ui_MobileAppConnector* ui;
|
Ui_MobileAppConnector* ui;
|
||||||
|
|
||||||
|
QString tempSecret;
|
||||||
|
WormholeClient* tempWormholeClient = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AppDataModel {
|
class AppDataModel {
|
||||||
@@ -105,4 +132,6 @@ private:
|
|||||||
static AppDataModel* instance;
|
static AppDataModel* instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // WEBSOCKETS_H
|
#endif // WEBSOCKETS_H
|
||||||
Reference in New Issue
Block a user