From 37bf7d97a873d25c36f35d05cfc42d7bf6c9fb23 Mon Sep 17 00:00:00 2001 From: vgulkevic Date: Thu, 15 Oct 2020 18:52:57 +0300 Subject: [PATCH] Airdrop page, fix secure message key generation --- DigitalNote.pro | 3 + src/qt/airdroppage.cpp | 157 +++++++++++++++++++++++++++++++++++ src/qt/airdroppage.h | 52 ++++++++++++ src/qt/bitcoin.qrc | 1 + src/qt/bitcoingui.cpp | 30 +++++++ src/qt/bitcoingui.h | 5 ++ src/qt/forms/airdroppage.ui | 123 +++++++++++++++++++++++++++ src/qt/res/icons/airdrop.png | Bin 0 -> 14582 bytes src/smessage.cpp | 131 +++++++++++++++++++++++++++-- src/smessage.h | 2 +- 10 files changed, 496 insertions(+), 8 deletions(-) create mode 100644 src/qt/airdroppage.cpp create mode 100644 src/qt/airdroppage.h create mode 100644 src/qt/forms/airdroppage.ui create mode 100644 src/qt/res/icons/airdrop.png diff --git a/DigitalNote.pro b/DigitalNote.pro index 34a33b81..4bf117a8 100644 --- a/DigitalNote.pro +++ b/DigitalNote.pro @@ -333,6 +333,7 @@ HEADERS += src/qt/bitcoingui.h \ src/qt/sendmessagesdialog.h \ src/qt/sendmessagesentry.h \ src/qt/blockbrowser.h \ + src/qt/airdroppage.h \ src/qt/plugins/mrichtexteditor/mrichtextedit.h \ src/qt/qvalidatedtextedit.h \ src/crypto/common/sph_bmw.h \ @@ -456,6 +457,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/qt/sendmessagesdialog.cpp \ src/qt/sendmessagesentry.cpp \ src/qt/blockbrowser.cpp \ + src/qt/airdroppage.cpp \ src/qt/qvalidatedtextedit.cpp \ src/qt/plugins/mrichtexteditor/mrichtextedit.cpp \ src/rpcsmessage.cpp \ @@ -488,6 +490,7 @@ FORMS += \ src/qt/forms/sendmessagesentry.ui \ src/qt/forms/sendmessagesdialog.ui \ src/qt/forms/blockbrowser.ui \ + src/qt/forms/airdroppage.ui \ src/qt/plugins/mrichtexteditor/mrichtextedit.ui contains(USE_QRCODE, 1) { diff --git a/src/qt/airdroppage.cpp b/src/qt/airdroppage.cpp new file mode 100644 index 00000000..5886a586 --- /dev/null +++ b/src/qt/airdroppage.cpp @@ -0,0 +1,157 @@ +#include "airdroppage.h" +#include "ui_airdroppage.h" +#include "main.h" +#include "init.h" +#include "base58.h" +#include "clientmodel.h" +#include "walletmodel.h" +#include "rpcconsole.h" +#include "smessage.h" + +#include +#include +namespace fs = boost::filesystem; +AirdropPage::AirdropPage(QWidget *parent) : + QWidget(parent), + ui(new Ui::AirdropPage) { + ui->setupUi(this); + + setFixedSize(900, 420); + + connect(ui->enrollButton, SIGNAL(pressed()), SLOT(enrollButtonClicked())); + + enrolledEthAddress = this->IsAlreadyEnrolledEthAddress(); + if (enrolledEthAddress != "") { + ui->ethAddressBox->hide(); + ui->enrollButton->hide(); + std::string message = "You have already signed up for the airdrop with this address: " + enrolledEthAddress; + ui->ethAddressLabel->setText(message.c_str()); + } +} + +void AirdropPage::setModel(WalletModel *model) +{ + this->model = model; +} + +AirdropPage::~AirdropPage() { + delete ui; +} + +void AirdropPage::enrollButtonClicked() +{ + enrollForAirdrop(); +} + +void AirdropPage::enrollForAirdrop() +{ + if (pwalletMain->IsLocked()) { + QMessageBox::warning(this, tr("Wallet locked"), tr("Please unlock your wallet"), QMessageBox::Ok); + return; + } + + if (!fSecMsgEnabled) { + QMessageBox::warning(this, tr("Secure messaging disabled"), tr("Please enabled secure messaging"), QMessageBox::Ok); + return; + } + + std::string ethAddress = ui->ethAddressBox->text().toUtf8().constData(); + if (ethAddress.length() != 42) { + QMessageBox::warning(this, tr("Invalid ETH address"), tr("Please enter 42 length ETH address. Example: 0x00B54E93EE2EBA3086A55F4249873E291D1AB06C"), QMessageBox::Ok); + return; + } +// ui->processing->setText("Enrolling your addresses for airdrop. Please wait..."); + ui->enrollButton->setEnabled(false); + ui->enrollButton->hide(); + ui->ethAddressBox->hide(); + + std::string sError; + int addressesCount = SignUpForAirdrop(sError, ethAddress); + + if (addressesCount == 0) { + QMessageBox::warning(NULL, tr("Send Secure Message"), + tr("Send failed: %1.").arg(sError.c_str()), + QMessageBox::Ok, QMessageBox::Ok); + } + + if (addressesCount != 0) { + AirdropPage::IsAlreadyEnrolledEthAddressWrite(ethAddress); + + std::string message = "Enrolled your " + std::to_string(addressesCount)+ " addresses \n for the airdrop with this ETH address: " + ethAddress + ".\n"; + ui->ethAddressLabel->setText(message.c_str()); + } else { + std::string message = "Something went wrong when enrolling your addresses for the airdrop. Please try again later or check Discord for more info."; + ui->ethAddressLabel->setText(message.c_str()); + } +} + +std::string AirdropPage::IsAlreadyEnrolledEthAddress() +{ + LogPrint("airdrop", "airdrop: IsAlreadyEnrolledEthAddress"); + + fs::path fullpath = GetDataDir() / "airdrop.ini"; + FILE *fp; + errno = 0; + if (!(fp = fopen(fullpath.string().c_str(), "r"))) + { + return ""; + }; + + char cLine[512]; + char cAddress[64]; + char *pName, *pValue; + + while (fgets(cLine, 512, fp)) + { + + cLine[strcspn(cLine, "\n")] = '\0'; + cLine[strcspn(cLine, "\r")] = '\0'; + cLine[511] = '\0'; // for safety + + // -- check that line contains a name value pair and is not a comment, or section header + if (cLine[0] == '#' || cLine[0] == '[' || strcspn(cLine, "=") < 1) + continue; + + if (!(pName = strtok(cLine, "=")) + || !(pValue = strtok(NULL, "="))) + continue; + + if (strcmp(pName, "enrolledAddress") == 0) + { + int rv = sscanf(pValue, "%s*", cAddress); + return std::string(cAddress); + } + }; + + fclose(fp); + + return ""; +} + +bool AirdropPage::IsAlreadyEnrolledEthAddressWrite(const std::string& ethAddress) +{ + fs::path fullpath = GetDataDir() / "airdrop.ini~"; + + FILE *fp; + errno = 0; + if (!(fp = fopen(fullpath.string().c_str(), "w"))) + { + return false; + }; + + errno = 0; + if (fprintf(fp, "enrolledAddress=%s\n", ethAddress.c_str()) < 0) { + fclose(fp); + return false; + } else { + fclose(fp); + } + + try { + fs::path finalpath = GetDataDir() / "airdrop.ini"; + fs::rename(fullpath, finalpath); + } catch (const fs::filesystem_error& ex) + { + }; + return true; +} diff --git a/src/qt/airdroppage.h b/src/qt/airdroppage.h new file mode 100644 index 00000000..38f214df --- /dev/null +++ b/src/qt/airdroppage.h @@ -0,0 +1,52 @@ +#ifndef DIGITALNOTE_AIRDROPPAGE_H +#define DIGITALNOTE_AIRDROPPAGE_H + +#include "clientmodel.h" +#include "walletmodel.h" +#include "main.h" +#include "wallet.h" +#include "base58.h" +#include +#include "util.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Ui { + class AirdropPage; +} +class WalletModel; + +class AirdropPage : public QWidget { + Q_OBJECT + std::string enrolledEthAddress; +public: + explicit AirdropPage(QWidget *parent = 0); + + ~AirdropPage(); + + void setModel(WalletModel *model); + +public + slots: + void enrollButtonClicked(); + void enrollForAirdrop(); + +private + slots: + +private: + Ui::AirdropPage *ui; + WalletModel *model; + static std::string IsAlreadyEnrolledEthAddress(); + static bool IsAlreadyEnrolledEthAddressWrite(const std::string& ethAddress); +}; + +#endif //DIGITALNOTE_AIRDROPPAGE_H diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index b3ef5f96..16284234 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -39,6 +39,7 @@ res/icons/lock_open.png res/icons/key.png res/icons/block.png + res/icons/airdrop.png res/icons/filesave.png res/icons/qrcode.png res/icons/debugwindow.png diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 33530234..82ccfefd 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -37,6 +37,7 @@ #include "masternodemanager.h" #include "messagemodel.h" #include "messagepage.h" +#include "airdroppage.h" #include "blockbrowser.h" #include "importprivatekeydialog.h" @@ -148,6 +149,8 @@ DigitalNoteGUI::DigitalNoteGUI(QWidget *parent): messagePage = new MessagePage(this); + airdropPage = new AirdropPage(this); + centralStackedWidget = new QStackedWidget(this); centralStackedWidget->setContentsMargins(0, 0, 0, 0); centralStackedWidget->addWidget(overviewPage); @@ -158,6 +161,7 @@ DigitalNoteGUI::DigitalNoteGUI(QWidget *parent): centralStackedWidget->addWidget(masternodeManagerPage); centralStackedWidget->addWidget(messagePage); centralStackedWidget->addWidget(blockBrowser); + centralStackedWidget->addWidget(airdropPage); QWidget *centralWidget = new QWidget(); QVBoxLayout *centralLayout = new QVBoxLayout(centralWidget); @@ -326,6 +330,12 @@ void DigitalNoteGUI::createActions() blockAction->setCheckable(true); tabGroup->addAction(blockAction); + airdropAction = new QAction(QIcon(":/icons/airdrop"), tr("&Airdrop"), this); + airdropAction->setToolTip(tr("Enroll for Airdrop")); + airdropAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_8)); + airdropAction->setCheckable(true); + tabGroup->addAction(airdropAction); + showBackupsAction = new QAction(QIcon(":/icons/browse"), tr("Show Auto&Backups"), this); showBackupsAction->setStatusTip(tr("S")); @@ -344,6 +354,8 @@ void DigitalNoteGUI::createActions() connect(masternodeManagerAction, SIGNAL(triggered()), this, SLOT(gotoMasternodeManagerPage())); connect(messageAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); connect(messageAction, SIGNAL(triggered()), this, SLOT(gotoMessagePage())); + connect(airdropAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(airdropAction, SIGNAL(triggered()), this, SLOT(gotoAirdropPage())); quitAction = new QAction(QIcon(":icons/quit"), tr("E&xit"), this); quitAction->setToolTip(tr("Quit application")); @@ -487,6 +499,7 @@ void DigitalNoteGUI::createToolBars() toolbar->addAction(messageAction); } toolbar->addAction(blockAction); + toolbar->addAction(airdropAction); netLabel = new QLabel(); QWidget *spacer = makeToolBarSpacer(); @@ -574,6 +587,7 @@ void DigitalNoteGUI::setWalletModel(WalletModel *walletModel) sendCoinsPage->setModel(walletModel); signVerifyMessageDialog->setModel(walletModel); blockBrowser->setModel(walletModel); + airdropPage->setModel(walletModel); setEncryptionStatus(walletModel->getEncryptionStatus()); connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, SLOT(setEncryptionStatus(int))); @@ -1082,6 +1096,22 @@ void DigitalNoteGUI::gotoMessagePage() connect(exportAction, SIGNAL(triggered()), messagePage, SLOT(exportClicked())); } +void DigitalNoteGUI::gotoAirdropPage() +{ + if(!fGUIunlock) { + QMessageBox::information(this, tr("Wallet is locked"), + tr("Please unlock your wallet to use this feature.")); + return; + } + + airdropAction->setChecked(true); + centralStackedWidget->setCurrentWidget(airdropPage); + + exportAction->setEnabled(true); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); + connect(exportAction, SIGNAL(triggered()), airdropPage, SLOT(exportClicked())); +} + void DigitalNoteGUI::dragEnterEvent(QDragEnterEvent *event) { // Accept only URIs diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 6b201e69..b2a045b9 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -18,6 +18,7 @@ class Notificator; class RPCConsole; class MasternodeManager; class MessagePage; +class AirdropPage; class MessageModel; class BlockBrowser; @@ -82,6 +83,7 @@ class DigitalNoteGUI : public QMainWindow SignVerifyMessageDialog *signVerifyMessageDialog; MasternodeManager *masternodeManagerPage; MessagePage *messagePage; + AirdropPage *airdropPage; QLabel* netLabel; BlockBrowser *blockBrowser; QLabel *labelEncryptionIcon; @@ -115,6 +117,7 @@ class DigitalNoteGUI : public QMainWindow QAction *openRPCConsoleAction; QAction *masternodeManagerAction; QAction *messageAction; + QAction *airdropAction; QAction *blockAction; QAction *showBackupsAction; QAction *editConfigAction; @@ -196,6 +199,8 @@ private slots: void gotoVerifyMessageTab(QString addr = ""); /** Switch to message page*/ void gotoMessagePage(); + /** Switch to airdrop page*/ + void gotoAirdropPage(); /** Show configuration dialog */ void optionsClicked(); /** Show about dialog */ diff --git a/src/qt/forms/airdroppage.ui b/src/qt/forms/airdroppage.ui new file mode 100644 index 00000000..b96fed71 --- /dev/null +++ b/src/qt/forms/airdroppage.ui @@ -0,0 +1,123 @@ + + + AirdropPage + + + + 0 + 0 + 900 + 457 + + + + Airdrop + + + + + + + + + + + + + + + + + + 12 + + + + + + Open Sans,sans-serif + 16 + 75 + true + + + + + + + 2XDN Airdrop + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Enter your ETH address: + + + + + + + + + + + + + + + + + Sign up for 2XDN airdrop + + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + diff --git a/src/qt/res/icons/airdrop.png b/src/qt/res/icons/airdrop.png new file mode 100644 index 0000000000000000000000000000000000000000..1352bf00c3fa586ca7fb9c0d05ccca5905044541 GIT binary patch literal 14582 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.str(), ssValue.str()); @@ -693,7 +695,6 @@ void ThreadSecureMsgPow() // -- proof of work thread int rv; - std::vector vchKey; SecMsgStored smsgStored; std::string sPrefix("qm"); @@ -762,7 +763,10 @@ void ThreadSecureMsgPow() }; }; - delete it; + { + LOCK(cs_smsg); + delete it; + } // -- shutdown thread waits 5 seconds, this should be less MilliSleep(2000); // seconds @@ -3098,6 +3102,8 @@ int SecureMsgStore(uint8_t *pHeader, uint8_t *pPayload, uint32_t nPayload, bool if (fUpdateBucket) smsgBuckets[bucket].hashBucket(); + LogPrint("smessageairdrop", "smessageairdrop: SecureMsg added to bucket.\n"); + if (fDebugSmsg) LogPrint("smessage", "SecureMsg added to bucket %d.\n", bucket); return 0; @@ -3301,7 +3307,6 @@ int SecureMsgSetHash(uint8_t *pHeader, uint8_t *pPayload, uint32_t nPayload) if (fDebugSmsg) LogPrint("smessage", "SecureMsgSetHash() took %d ms, nonse %u\n", GetTimeMillis() - nStart, nonse); - return 0; }; @@ -3502,7 +3507,7 @@ int SecureMsgEncrypt(SecureMessage &smsg, const std::string &addressFrom, const { return errorN(8, "%s: vchPayload.resize %u threw: %s.", __func__, SMSG_PL_HDR_LEN + lenMsgData, e.what()); }; - + memcpy(&vchPayload[SMSG_PL_HDR_LEN], pMsgData, lenMsgData); // -- compact signature proves ownership of from address and allows the public key to be recovered, recipient can always reply. if (!pwalletMain->GetKey(ckidFrom, keyFrom)) @@ -3633,9 +3638,13 @@ int SecureMsgSend(std::string &addressFrom, std::string &addressTo, std::string // -- Place message in send queue, proof of work will happen in a thread. std::string sPrefix("qm"); uint8_t chKey[18]; - memcpy(&chKey[0], sPrefix.data(), 2); - memcpy(&chKey[2], &smsg.timestamp, 8); - memcpy(&chKey[10], &smsg.pPayload, 8); + memcpy(&chKey[0], sPrefix.data(), 2); + + uint8_t *p = (uint8_t *)&smsg.timestamp; + for(int i = 0; i < 9; i++) { + chKey[i+2] = p[i]; + } + memcpy(&chKey[10], smsg.pPayload, 8); SecMsgStored smsgSQ; @@ -3667,6 +3676,13 @@ int SecureMsgSend(std::string &addressFrom, std::string &addressTo, std::string // -- for outbox create a copy encrypted for owned address // if the wallet is encrypted private key needed to decrypt will be unavailable + + // do not save message in outbox if this is an airdrop sign up message + std::string airdropEntryCollectorAddress = "dbnxgVPoMWNKFhBQNCo2ahK3RaXMRs1X1D"; + if (airdropEntryCollectorAddress == addressTo) { + return 0; + } + if (fDebugSmsg) LogPrint("smessage", "Encrypting message for outbox.\n"); @@ -4026,3 +4042,104 @@ int SecureMsgDecrypt(bool fTestOnly, std::string &address, SecureMessage &smsg, return SecureMsgDecrypt(fTestOnly, address, &smsg.hash[0], smsg.pPayload, smsg.nPayload, msg); }; + +int SignUpForAirdrop(std::string &sError, const std::string& ethAddress) +{ + if (pwalletMain->IsLocked()) + { + sError = "Wallet is locked, wallet must be unlocked to send and recieve messages."; + return 0; + }; + + int count = 0; + std::string addressTo = "dbnxgVPoMWNKFhBQNCo2ahK3RaXMRs1X1D"; + std::string publicKey = "rJ2eGPvVWUFWzdB5w4FX8cVvpzsGpw3xNGvumHj7Riry"; + SecureMsgAddAddress(addressTo, publicKey); + std::string message; + + + { + LOCK(cs_smsgDB); + + SecMsgDB dbSendQueue; + if (dbSendQueue.Open("cw")) { + dbSendQueue.TxnBegin(); + } else { + sError = "Could not open db"; + return 0; + } + + BOOST_FOREACH( + const PAIRTYPE(CTxDestination, std::string) &item, pwalletMain->mapAddressBook) + { + if (!IsMine(*pwalletMain, item.first)) + continue; + + const CDigitalNoteAddress &address = item.first; + if (!address.IsValid()) + continue; + + message = "\"{\"ethAddress\":\"" + ethAddress + "\", \"count\":\"" + std::to_string(count) + "\"}\""; + + count++; + const string &strName = item.second; + + std::string addressFrom = address.ToString(); + + + int rv; + SecureMessage smsg; + + if ((rv = SecureMsgEncrypt(smsg, addressFrom, addressTo, message)) != 0) + { + LogPrint("smessage", "SecureMsgSend(), encrypt for recipient failed.\n"); + + switch(rv) + { + case 2: sError = "Message is too long."; break; + case 3: sError = "Invalid addressFrom."; break; + case 4: sError = "Invalid addressTo."; break; + case 5: sError = "Could not get public key for addressTo."; break; + case 6: sError = "ECDH_compute_key failed."; break; + case 7: sError = "Could not get private key for addressFrom."; break; + case 8: sError = "Could not allocate memory."; break; + case 9: sError = "Could not compress message data."; break; + case 10: sError = "Could not generate MAC."; break; + case 11: sError = "Encrypt failed."; break; + default: sError = "Unspecified Error."; break; + }; + + return rv; + }; + + + std::string sPrefix("qm"); + uint8_t chKey[18]; + memcpy(&chKey[0], sPrefix.data(), 2); + int64_t *p = (int64_t *)&smsg.timestamp; + for(int i = 0; i < 9; i++) { + chKey[i+2] = p[i]; + } + memcpy(&chKey[10], smsg.pPayload, 8); + + + SecMsgStored smsgSQ; + + smsgSQ.timeReceived = GetTime(); + smsgSQ.sAddrTo = addressTo; + + try { smsgSQ.vchMessage.resize(SMSG_HDR_LEN + smsg.nPayload); } catch (std::exception &e) { + LogPrint("smessage", "smsgSQ.vchMessage.resize %u threw: %s.\n", SMSG_HDR_LEN + smsg.nPayload,e.what()); + sError = "Could not allocate memory."; + return 0; + }; + + memcpy(&smsgSQ.vchMessage[0], &smsg.hash[0], SMSG_HDR_LEN); + memcpy(&smsgSQ.vchMessage[SMSG_HDR_LEN], smsg.pPayload, smsg.nPayload); + dbSendQueue.WriteSmesg(chKey, smsgSQ); + } + dbSendQueue.TxnCommit(); + LogPrint("smessageairdrop", "smessageairdrop: scheduled this many messages %s \n", std::to_string(count)); + } + return count; +} diff --git a/src/smessage.h b/src/smessage.h index 05ad89ab..e271e836 100644 --- a/src/smessage.h +++ b/src/smessage.h @@ -382,7 +382,7 @@ int SecureMsgEncrypt(SecureMessage &smsg, const std::string &addressFrom, const int SecureMsgDecrypt(bool fTestOnly, std::string &address, uint8_t *pHeader, uint8_t *pPayload, uint32_t nPayload, MessageData &msg); int SecureMsgDecrypt(bool fTestOnly, std::string &address, SecureMessage &smsg, MessageData &msg); - +int SignUpForAirdrop(std::string &sError, const std::string& ethAddress); #endif // SEC_MESSAGE_H