Browse Source

Wormhole connection

pull/45/head
Aditya Kulkarni 5 years ago
parent
commit
445c2845da
  1. 4
      src/logger.cpp
  2. 11
      src/mainwindow.cpp
  3. 6
      src/mainwindow.h
  4. 93
      src/websockets.cpp
  5. 35
      src/websockets.h

4
src/logger.cpp

@ -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");

11
src/mainwindow.cpp

@ -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;
} }

6
src/mainwindow.h

@ -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;

93
src/websockets.cpp

@ -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);

35
src/websockets.h

@ -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
Loading…
Cancel
Save