aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt18
-rw-r--r--src/gpg/GpgContext.cpp9
-rw-r--r--src/gpg/GpgFileOpera.cpp2
-rw-r--r--src/gpg/GpgUID.cpp26
-rw-r--r--src/server/CMakeLists.txt6
-rw-r--r--src/server/ComUtils.cpp81
-rwxr-xr-xsrc/ui/FileEncryptionDialog.cpp2
-rw-r--r--src/ui/KeyUploadDialog.cpp2
-rwxr-xr-xsrc/ui/SettingsDialog.cpp166
-rw-r--r--src/ui/ShowCopyDialog.cpp26
-rw-r--r--src/ui/main_window/MainWindowSlotFunction.cpp193
-rw-r--r--src/ui/widgets/EditorPage.cpp2
-rw-r--r--src/ui/widgets/InfoBoardWidget.cpp3
-rw-r--r--src/ui/widgets/KeyList.cpp148
14 files changed, 543 insertions, 141 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ad56423d..cdd0bfe7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,8 +1,7 @@
-set(ALL_SOURCE_FILE)
-
add_subdirectory(gpg)
add_subdirectory(ui)
add_subdirectory(smtp)
+add_subdirectory(server)
aux_source_directory(. BASE_SOURCE)
@@ -121,23 +120,26 @@ else()
add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
endif()
+set(GPGFRONTEND_LIBS smtp gpgfrontend-ui server gpg)
+set(QT_DEPENDENCY_LIBS Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core)
+
IF (MINGW)
message(STATUS "Link Application Static Library For MINGW")
target_link_libraries(${AppName}
- smtp gpgfrontend-ui gpg
- Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core
+ ${GPGFRONTEND_LIBS}
+ ${QT_DEPENDENCY_LIBS}
crypto ssl)
elseif(APPLE)
message(STATUS "Link Application Static Library For macOS")
target_link_libraries(${AppName}
- smtp gpgfrontend-ui gpg
- Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core
+ ${GPGFRONTEND_LIBS}
+ ${QT_DEPENDENCY_LIBS}
crypto ssl)
else()
message(STATUS "Link Application Static Library For UNIX")
target_link_libraries(${AppName}
- smtp gpgfrontend-ui gpg
- Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core
+ ${GPGFRONTEND_LIBS}
+ ${QT_DEPENDENCY_LIBS}
crypto ssl pthread)
endif()
diff --git a/src/gpg/GpgContext.cpp b/src/gpg/GpgContext.cpp
index 72c04ac9..ff32edd8 100644
--- a/src/gpg/GpgContext.cpp
+++ b/src/gpg/GpgContext.cpp
@@ -694,13 +694,12 @@ namespace GpgME {
}
gpg_error_t
- GpgContext::sign(const QVector<GpgKey> &keys, const QByteArray &inBuffer, QByteArray *outBuffer, bool detached,
+ GpgContext::sign(const QVector<GpgKey> &keys, const QByteArray &inBuffer, QByteArray *outBuffer, gpgme_sig_mode_t mode,
gpgme_sign_result_t *result) {
gpgme_error_t gpgmeError;
gpgme_data_t dataIn, dataOut;
gpgme_sign_result_t m_result;
- gpgme_sig_mode_t mode;
if (keys.isEmpty()) {
QMessageBox::critical(nullptr, tr("Key Selection"), tr("No Private Key Selected"));
@@ -729,12 +728,6 @@ namespace GpgME {
mode settings of the context are ignored.
*/
- if (detached) {
- mode = GPGME_SIG_MODE_DETACH;
- } else {
- mode = GPGME_SIG_MODE_CLEAR;
- }
-
gpgmeError = gpgme_op_sign(mCtx, dataIn, dataOut, mode);
checkErr(gpgmeError);
diff --git a/src/gpg/GpgFileOpera.cpp b/src/gpg/GpgFileOpera.cpp
index 9395bd17..5d924349 100644
--- a/src/gpg/GpgFileOpera.cpp
+++ b/src/gpg/GpgFileOpera.cpp
@@ -114,7 +114,7 @@ gpgme_error_t GpgFileOpera::signFile(GpgME::GpgContext *ctx, QVector<GpgKey> &ke
auto outBuffer = QByteArray();
infile.close();
- auto error = ctx->sign(keys, inBuffer, &outBuffer, true, result);
+ auto error = ctx->sign(keys, inBuffer, &outBuffer, GPGME_SIG_MODE_DETACH, result);
if (gpg_err_code(error) != GPG_ERR_NO_ERROR) return error;
diff --git a/src/gpg/GpgUID.cpp b/src/gpg/GpgUID.cpp
index f8f7e8fa..0dc6abfd 100644
--- a/src/gpg/GpgUID.cpp
+++ b/src/gpg/GpgUID.cpp
@@ -1,6 +1,26 @@
-//
-// Created by eric on 2021/5/22.
-//
+/**
+ * This file is part of GPGFrontend.
+ *
+ * GPGFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
#include "gpg/GpgUID.h"
diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt
new file mode 100644
index 00000000..867be076
--- /dev/null
+++ b/src/server/CMakeLists.txt
@@ -0,0 +1,6 @@
+aux_source_directory(. SERVER_SOURCE)
+
+add_library(server STATIC ${SERVER_SOURCE})
+
+target_link_libraries(server
+ Qt5::Network Qt5::Widgets Qt5::Core)
diff --git a/src/server/ComUtils.cpp b/src/server/ComUtils.cpp
new file mode 100644
index 00000000..637b5c12
--- /dev/null
+++ b/src/server/ComUtils.cpp
@@ -0,0 +1,81 @@
+/**
+ * This file is part of GPGFrontend.
+ *
+ * GPGFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "server/ComUtils.h"
+
+/**
+ * check server reply if it can parse into a json object
+ * @param reply reply data in byte array
+ * @return if successful
+ */
+bool ComUtils::checkServerReply(const QByteArray &reply) {
+
+ /**
+ * Server Reply Format(Except Timeout)
+ * {
+ * "status": 200,
+ * "message": "OK",
+ * "data" : {
+ * ...
+ * }
+ * }
+ */
+
+ // check if reply is a json object
+ if (replyDoc.Parse(reply).HasParseError() || !replyDoc.IsObject()) {
+ QMessageBox::critical(this, tr("Error"), tr("Unknown Error"));
+ return false;
+ }
+
+ // check status(int) and message(string)
+ if (replyDoc.HasMember("status") && replyDoc.HasMember("message")
+ && replyDoc["status"].IsInt() && replyDoc["message"].IsString()) {
+
+ int status = replyDoc["status"].GetInt();
+ QString message = replyDoc["status"].GetString();
+
+ // check status code if successful (200-299)
+ // check data object
+ if (status / 10 == 2 && replyDoc.HasMember("data") && replyDoc["data"].IsObject()) {
+ dataVal = replyDoc["data"].GetObjectA();
+ is_good = true;
+ return true;
+ } else QMessageBox::critical(this, tr("Error"), message);
+
+ } else QMessageBox::critical(this, tr("Error"), tr("Unknown Reply Format"));
+}
+
+/**
+ * get value in data
+ * @param key key of value
+ * @return value in string format
+ */
+QString ComUtils::getDataValue(const QString &key) {
+ if (is_good) {
+ auto k_byte_array = key.toUtf8();
+ if (dataVal.HasMember(k_byte_array.data())) {
+ return dataVal[k_byte_array.data()].GetString();
+ } else return {};
+ } else return {};
+}
diff --git a/src/ui/FileEncryptionDialog.cpp b/src/ui/FileEncryptionDialog.cpp
index e92dfc90..d9bc7ce2 100755
--- a/src/ui/FileEncryptionDialog.cpp
+++ b/src/ui/FileEncryptionDialog.cpp
@@ -229,7 +229,7 @@ void FileEncryptionDialog::slotExecuteAction() {
if (mAction == Sign) {
qDebug() << "Action Sign";
- gpgme_error_t err = mCtx->sign(keys, inBuffer, outBuffer, true);
+ gpgme_error_t err = mCtx->sign(keys, inBuffer, outBuffer, GPGME_SIG_MODE_DETACH);
if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) {
qDebug() << "Error" << gpgme_strerror(err);
QMessageBox::warning(this, tr("Error"),
diff --git a/src/ui/KeyUploadDialog.cpp b/src/ui/KeyUploadDialog.cpp
index faf892f0..ab38569f 100644
--- a/src/ui/KeyUploadDialog.cpp
+++ b/src/ui/KeyUploadDialog.cpp
@@ -24,8 +24,6 @@
#include "ui/KeyUploadDialog.h"
-#include <utility>
-
KeyUploadDialog::KeyUploadDialog(GpgME::GpgContext *ctx, const QVector<GpgKey> &keys, QWidget *parent)
: appPath(qApp->applicationDirPath()),
settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat),
diff --git a/src/ui/SettingsDialog.cpp b/src/ui/SettingsDialog.cpp
index 1732d718..00b26e7b 100755
--- a/src/ui/SettingsDialog.cpp
+++ b/src/ui/SettingsDialog.cpp
@@ -26,6 +26,9 @@
#include "smtp/SmtpMime"
#include "ui/WaitingDialog.h"
+#include "rapidjson/document.h"
+#include "rapidjson/prettywriter.h"
+
SettingsDialog::SettingsDialog(GpgME::GpgContext *ctx, QWidget *parent)
: QDialog(parent) {
mCtx = ctx;
@@ -132,14 +135,15 @@ GeneralTab::GeneralTab(GpgME::GpgContext *ctx, QWidget *parent)
mCtx = ctx;
/*****************************************
- * remember Password-Box
+ * GpgFrontend Server
*****************************************/
- auto *rememberPasswordBox = new QGroupBox(tr("Remember Password"));
- auto *rememberPasswordBoxLayout = new QHBoxLayout();
- rememberPasswordCheckBox =
- new QCheckBox(tr("Remember password until closing gpg4usb"), this);
- rememberPasswordBoxLayout->addWidget(rememberPasswordCheckBox);
- rememberPasswordBox->setLayout(rememberPasswordBoxLayout);
+ auto *serverBox = new QGroupBox(tr("GpgFrontend Server"));
+ auto *serverBoxLayout = new QVBoxLayout();
+ serverSelectBox = new QComboBox();
+ serverBoxLayout->addWidget(serverSelectBox);
+ serverBoxLayout->addWidget(new QLabel(
+ tr("Server that provides short key and key exchange services")));
+ serverBox->setLayout(serverBoxLayout);
/*****************************************
* Save-Checked-Keys-Box
@@ -171,7 +175,7 @@ GeneralTab::GeneralTab(GpgME::GpgContext *ctx, QWidget *parent)
langSelectBox = new QComboBox;
lang = SettingsDialog::listLanguages();
- foreach (QString l, lang) { langSelectBox->addItem(l); }
+ for (const auto &l: lang) { langSelectBox->addItem(l); }
langBoxLayout->addWidget(langSelectBox);
langBoxLayout->addWidget(
@@ -186,7 +190,10 @@ GeneralTab::GeneralTab(GpgME::GpgContext *ctx, QWidget *parent)
*****************************************/
auto *ownKeyBox = new QGroupBox(tr("Own key"));
auto *ownKeyBoxLayout = new QVBoxLayout();
+ auto *ownKeyServiceTokenLayout = new QHBoxLayout();
ownKeySelectBox = new QComboBox;
+ getServiceTokenButton = new QPushButton(tr("Get Service Token"));
+ serviceTokenLabel = new QLabel(tr("No Service Token Found"));
ownKeyBox->setLayout(ownKeyBoxLayout);
mKeyList = new KeyList(mCtx);
@@ -204,16 +211,22 @@ GeneralTab::GeneralTab(GpgME::GpgContext *ctx, QWidget *parent)
}
connect(ownKeySelectBox, SIGNAL(currentIndexChanged(int)), this,
SLOT(slotOwnKeyIdChanged()));
+ connect(getServiceTokenButton, SIGNAL(clicked(bool)), this,
+ SLOT(slotGetServiceToken()));
ownKeyBoxLayout->addWidget(new QLabel(
tr("Key pair for synchronization and identity authentication")));
ownKeyBoxLayout->addWidget(ownKeySelectBox);
+ ownKeyBoxLayout->addLayout(ownKeyServiceTokenLayout);
+ ownKeyServiceTokenLayout->addWidget(getServiceTokenButton);
+ ownKeyServiceTokenLayout->addWidget(serviceTokenLabel);
+ ownKeyServiceTokenLayout->stretch(0);
/*****************************************
* Mainlayout
*****************************************/
auto *mainLayout = new QVBoxLayout;
- mainLayout->addWidget(rememberPasswordBox);
+ mainLayout->addWidget(serverBox);
mainLayout->addWidget(saveCheckedKeysBox);
mainLayout->addWidget(importConfirmationBox);
mainLayout->addWidget(langBox);
@@ -235,6 +248,15 @@ void GeneralTab::setSettings() {
saveCheckedKeysCheckBox->setCheckState(Qt::Checked);
}
+ auto serverList = settings.value("general/gpgfrontendServerList").toStringList();
+ if(serverList.empty()) {
+ serverList.append("service.gpgfrontend.pub");
+ }
+ for(const auto &s : serverList)
+ serverSelectBox->addItem(s);
+ serverSelectBox->setCurrentText(settings.value("general/currentGpgfrontendServer",
+ "service.gpgfrontend.pub").toString());
+
// Language setting
QString langKey = settings.value("int/lang").toString();
QString langValue = lang.value(langKey);
@@ -242,16 +264,22 @@ void GeneralTab::setSettings() {
langSelectBox->setCurrentIndex(langSelectBox->findText(langValue));
}
- QString ownKeyId = settings.value("general/ownKeyId").toString();
- qDebug() << "OwnKeyId" << ownKeyId;
- if (ownKeyId.isEmpty()) {
+ QString own_key_id = settings.value("general/ownKeyId").toString();
+ qDebug() << "OwnKeyId" << own_key_id;
+ if (own_key_id.isEmpty()) {
ownKeySelectBox->setCurrentText("<none>");
} else {
- const auto text = keyIds.find(ownKeyId).value();
- qDebug() << "OwnKey" << ownKeyId << text;
+ const auto text = keyIds.find(own_key_id).value();
+ qDebug() << "OwnKey" << own_key_id << text;
ownKeySelectBox->setCurrentText(text);
}
+ serviceToken = settings.value("general/serviceToken").toString();
+ qDebug() << "Load Service Token" << serviceToken;
+ if(!serviceToken.isEmpty()) {
+ serviceTokenLabel->setText(serviceToken);
+ }
+
// Get own key information from keydb/gpg.conf (if contained)
if (settings.value("general/confirmImportKeys", Qt::Checked).toBool()) {
importConfirmationCheckBox->setCheckState(Qt::Checked);
@@ -265,12 +293,25 @@ void GeneralTab::setSettings() {
void GeneralTab::applySettings() {
settings.setValue("keys/saveKeyChecked",
saveCheckedKeysCheckBox->isChecked());
- // TODO: clear passwordCache instantly on unset rememberPassword
- settings.setValue("general/rememberPassword",
- rememberPasswordCheckBox->isChecked());
+
+ settings.setValue("general/currentGpgfrontendServer",
+ serverSelectBox->currentText());
+
+ auto *serverList = new QStringList();
+ for(int i = 0; i < serverSelectBox->count(); i++)
+ serverList->append(serverSelectBox->itemText(i));
+ settings.setValue("general/gpgfrontendServerList",
+ *serverList);
+ delete serverList;
+
settings.setValue("int/lang", lang.key(langSelectBox->currentText()));
+
settings.setValue("general/ownKeyId",
keyIdsList[ownKeySelectBox->currentIndex()]);
+
+ settings.setValue("general/serviceToken",
+ serviceToken);
+
settings.setValue("general/confirmImportKeys",
importConfirmationCheckBox->isChecked());
}
@@ -279,6 +320,81 @@ void GeneralTab::slotLanguageChanged() { emit signalRestartNeeded(true); }
void GeneralTab::slotOwnKeyIdChanged() {
// Set ownKeyId to currently selected
+ this->serviceTokenLabel->setText(tr("No Service Token Found"));
+ serviceToken.clear();
+}
+
+void GeneralTab::slotGetServiceToken() {
+ QUrl reqUrl("http://127.0.0.1:9048/user");
+ QNetworkRequest request(reqUrl);
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+
+ // Building Post Data
+ QByteArray keyDataBuf;
+
+ const auto keyId = keyIdsList[ownKeySelectBox->currentIndex()];
+
+ qDebug() << "KeyId" << keyIdsList[ownKeySelectBox->currentIndex()];
+
+ if(keyId.isEmpty()) {
+ QMessageBox::critical(this, tr("Invalid Operation"), tr("Own Key can not be None while getting service token."));
+ return;
+ }
+
+ QStringList selectedKeyIds(keyIdsList[ownKeySelectBox->currentIndex()]);
+ mCtx->exportKeys(&selectedKeyIds, &keyDataBuf);
+
+ qDebug() << "keyDataBuf" << keyDataBuf;
+
+ rapidjson::Value p, v;
+
+ rapidjson::Document doc;
+ doc.SetObject();
+
+ p.SetString(keyDataBuf.constData(), keyDataBuf.count());
+
+ auto version = qApp->applicationVersion();
+ v.SetString(version.toUtf8().constData(), qApp->applicationVersion().count());
+
+ doc.AddMember("publicKey", p, doc.GetAllocator());
+ doc.AddMember("version", v, doc.GetAllocator());
+
+ rapidjson::StringBuffer sb;
+ rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
+ doc.Accept(writer);
+
+ QByteArray postData(sb.GetString());
+
+ QNetworkReply *reply = manager.post(request, postData);
+
+ auto dialog = new WaitingDialog("Getting Token From Server", this);
+ dialog->show();
+
+ while (reply->isRunning()) {
+ QApplication::processEvents();
+ }
+
+ dialog->close();
+
+ if(reply->error() == QNetworkReply::NoError) {
+ rapidjson::Document docReply;
+ docReply.Parse(reply->readAll().constData());
+ QString serviceTokenTemp = docReply["serviceToken"].GetString();
+ if(checkUUIDFormat(serviceTokenTemp)) {
+ serviceToken = serviceTokenTemp;
+ qDebug() << "Get Service Token" << serviceToken;
+ serviceTokenLabel->setText(serviceToken);
+ } else {
+ QMessageBox::critical(this, tr("Error"), tr("Invalid Service Token Format"));
+ }
+ } else {
+ QMessageBox::critical(this, tr("Error"), reply->errorString());
+ }
+
+}
+
+bool GeneralTab::checkUUIDFormat(const QString& uuid) {
+ return re_uuid.match(uuid).hasMatch();
}
SendMailTab::SendMailTab(QWidget *parent)
@@ -304,7 +420,7 @@ SendMailTab::SendMailTab(QWidget *parent)
connectionTypeComboBox->addItem("STARTTLS");
defaultSender = new QLineEdit();;
- checkConnectionButton = new QPushButton("Check Connection");
+ checkConnectionButton = new QPushButton(tr("Check Connection"));
auto layout = new QGridLayout();
layout->addWidget(enableCheckBox, 0, 0);
@@ -378,13 +494,11 @@ void SendMailTab::applySettings() {
void SendMailTab::slotCheckConnection() {
- SmtpClient::ConnectionType connectionType = SmtpClient::ConnectionType::TcpConnection;
-
- if (connectionTypeComboBox->currentText() == "SSL") {
+ SmtpClient::ConnectionType connectionType;
+ const auto selectedConnType = connectionTypeComboBox->currentText();
+ if (selectedConnType == "SSL") {
connectionType = SmtpClient::ConnectionType::SslConnection;
- } else if (connectionTypeComboBox->currentText() == "TLS") {
- connectionType = SmtpClient::ConnectionType::TlsConnection;
- } else if (connectionTypeComboBox->currentText() == "STARTTLS") {
+ } else if (selectedConnType == "TLS" || selectedConnType == "STARTTLS") {
connectionType = SmtpClient::ConnectionType::TlsConnection;
} else {
connectionType = SmtpClient::ConnectionType::TcpConnection;
@@ -392,9 +506,6 @@ void SendMailTab::slotCheckConnection() {
SmtpClient smtp(smtpAddress->text(), portSpin->value(), connectionType);
- // We need to set the username (your email address) and the password
- // for smtp authentification.
-
smtp.setUser(username->text());
smtp.setPassword(password->text());
@@ -648,6 +759,7 @@ void KeyserverTab::setSettings() {
qDebug() << "KeyserverTab ListItemText" << comboBox->itemText(i);
}
settings.setValue("keyserver/keyServerList", *keyServerList);
+ delete keyServerList;
settings.setValue("keyserver/defaultKeyServer", comboBox->currentText());
}
diff --git a/src/ui/ShowCopyDialog.cpp b/src/ui/ShowCopyDialog.cpp
new file mode 100644
index 00000000..58a6cf0a
--- /dev/null
+++ b/src/ui/ShowCopyDialog.cpp
@@ -0,0 +1,26 @@
+//
+// Created by Administrator on 2021/7/21.
+//
+
+#include "ui/ShowCopyDialog.h"
+
+ShowCopyDialog::ShowCopyDialog(const QString &text, QWidget *parent) : QDialog(parent) {
+ textEdit = new QTextEdit();
+ textEdit->setReadOnly(true);
+ textEdit->setLineWrapMode(QTextEdit::WidgetWidth);
+ textEdit->setText(text);
+ copyButton = new QPushButton("Copy");
+ connect(copyButton, SIGNAL(clicked(bool)), this, SLOT(slotCopyText()));
+
+ auto *layout = new QVBoxLayout();
+ layout->addWidget(textEdit);
+ layout->addWidget(copyButton);
+
+ this->setModal(true);
+ this->setLayout(layout);
+}
+
+void ShowCopyDialog::slotCopyText() {
+ QClipboard *cb = QApplication::clipboard();
+ cb->setText(textEdit->toPlainText());
+}
diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp
index 4bcee080..736fecb5 100644
--- a/src/ui/main_window/MainWindowSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowSlotFunction.cpp
@@ -23,7 +23,12 @@
*/
#include "MainWindow.h"
+#include "server/ComUtils.h"
#include "ui/SendMailDialog.h"
+#include "ui/ShowCopyDialog.h"
+
+#include "rapidjson/document.h"
+#include "rapidjson/prettywriter.h"
void MainWindow::slotEncrypt() {
@@ -77,6 +82,7 @@ void MainWindow::slotEncrypt() {
edit->slotFillTextEditWithText(*tmp2);
infoBoard->associateTextEdit(edit->curTextPage());
+ // check result analyse status
if (resultAnalyse->getStatus() < 0)
infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL);
else if (resultAnalyse->getStatus() > 0)
@@ -84,10 +90,11 @@ void MainWindow::slotEncrypt() {
else
infoBoard->slotRefresh(reportText, INFO_ERROR_WARN);
+ // set optional actions
if (resultAnalyse->getStatus() >= 0) {
infoBoard->resetOptionActionsMenu();
infoBoard->addOptionalAction("Send Mail", [this]() {
- if(settings.value("sendMail/enable", false).toBool())
+ if (settings.value("sendMail/enable", false).toBool())
new SendMailDialog(edit->curTextPage()->toPlainText(), this);
else {
QMessageBox::warning(nullptr,
@@ -134,7 +141,7 @@ void MainWindow::slotSign() {
gpgme_error_t error;
auto thread = QThread::create([&]() {
- error = mCtx->sign(keys, edit->curTextPage()->toPlainText().toUtf8(), tmp, false, &result);
+ error = mCtx->sign(keys, edit->curTextPage()->toPlainText().toUtf8(), tmp, GPGME_SIG_MODE_CLEAR, &result);
});
connect(thread, SIGNAL(finished(QPrivateSignal)), thread, SLOT(deleteLater()));
thread->start();
@@ -361,7 +368,7 @@ void MainWindow::slotEncryptSign() {
if (status >= 0) {
infoBoard->resetOptionActionsMenu();
infoBoard->addOptionalAction("Send Mail", [this]() {
- if(settings.value("sendMail/enable", false).toBool())
+ if (settings.value("sendMail/enable", false).toBool())
new SendMailDialog(edit->curTextPage()->toPlainText(), this);
else {
QMessageBox::warning(nullptr,
@@ -369,6 +376,15 @@ void MainWindow::slotEncryptSign() {
tr("Please go to the settings interface to enable and configure this function."));
}
});
+ infoBoard->addOptionalAction("Shorten Crypt Text", [this]() {
+ if (settings.value("general/serviceToken").toString().isEmpty())
+ QMessageBox::warning(nullptr,
+ tr("Service Token Empty"),
+ tr("Please go to the settings interface to set Own Key and get Service Token."));
+ else {
+ shortenCryptText();
+ }
+ });
}
delete resultAnalyseEncr;
@@ -385,7 +401,18 @@ void MainWindow::slotDecryptVerify() {
if (edit->slotCurPageTextEdit() != nullptr) {
auto *decrypted = new QByteArray();
- QByteArray text = edit->curTextPage()->toPlainText().toUtf8();
+ QString plainText = edit->curTextPage()->toPlainText();
+
+
+ if (plainText.trimmed().startsWith("[GpgFrontend_ShortCrypto]://")) {
+ auto cryptoText = getCryptText(plainText);
+ if (!cryptoText.isEmpty()) {
+ plainText = cryptoText;
+ }
+ }
+
+ QByteArray text = plainText.toUtf8();
+
GpgME::GpgContext::preventNoDataErr(&text);
gpgme_decrypt_result_t d_result = nullptr;
@@ -435,6 +462,160 @@ void MainWindow::slotDecryptVerify() {
}
}
+/**
+ * get full size crypt text from server using short crypto text
+ * @param shortenCryptoText short crypto text([GpgFrontend_ShortCrypto]://)
+ * @return
+ */
+QString MainWindow::getCryptText(const QString &shortenCryptoText) {
+ QString host = settings.value("general/currentGpgfrontendServer",
+ "service.gpgfrontend.pub").toString();
+
+ QString ownKeyId = settings.value("general/ownKeyId").toString();
+
+ GpgKey key = mCtx->getKeyById(ownKeyId);
+ if (!key.good) {
+ QMessageBox::critical(this, tr("Invalid Own Key"), tr("Own Key can not be use to do any operation."));
+ return {};
+ }
+
+ QString serviceToken = settings.value("general/serviceToken").toString();
+ if (serviceToken.isEmpty()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Please obtain a Service Token from the server in the settings."));
+ return {};
+ }
+
+ QUrl reqUrl("http://127.0.0.1:9048/text/get");
+ QNetworkRequest request(reqUrl);
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+
+ // Sign Shorten Text
+ QVector keys{key};
+ QByteArray outSignText;
+ mCtx->sign(keys, shortenCryptoText.toUtf8(), &outSignText, GPGME_SIG_MODE_NORMAL);
+ auto outSignTextBase64 = outSignText.toBase64();
+
+ rapidjson::Document doc;
+ doc.SetObject();
+
+ rapidjson::Value s, t;
+
+ // Signature
+ s.SetString(outSignTextBase64.constData(), outSignTextBase64.count());
+ // Service Token
+ const auto t_byte_array = serviceToken.toUtf8();
+ t.SetString(t_byte_array.constData(), t_byte_array.count());
+
+ doc.AddMember("signature", s, doc.GetAllocator());
+ doc.AddMember("serviceToken", t, doc.GetAllocator());
+
+ rapidjson::StringBuffer sb;
+ rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
+ doc.Accept(writer);
+
+ QByteArray postData(sb.GetString());
+ qDebug() << "postData" << QString::fromUtf8(postData);
+
+ QNetworkReply *reply = networkAccessManager->post(request, postData);
+
+ auto dialog = new WaitingDialog("Getting Crypt Text From Server", this);
+ dialog->show();
+
+ while (reply->isRunning()) {
+ QApplication::processEvents();
+ }
+
+ dialog->close();
+
+ QByteArray replyData = reply->readAll().constData();
+ auto comUtils = new ComUtils(this);
+ if (comUtils->checkServerReply(replyData)) {
+ //TODO Logic
+ } else QMessageBox::critical(this, tr("Error"), tr("Unknown Error"));
+
+ return {};
+}
+
+void MainWindow::shortenCryptText() {
+
+ QString serviceToken = settings.value("general/serviceToken").toString();
+ QString ownKeyId = settings.value("general/ownKeyId").toString();
+
+ QByteArray cryptoText = edit->curTextPage()->toPlainText().toUtf8();
+
+ QUrl reqUrl("http://127.0.0.1:9048/text/new");
+ QNetworkRequest request(reqUrl);
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+
+ GpgKey key = mCtx->getKeyById(ownKeyId);
+ if (!key.good) {
+ QMessageBox::critical(this, tr("Invalid Own Key"), tr("Own Key can not be use to do any operation."));
+ return;
+ }
+
+ QCryptographicHash ch(QCryptographicHash::Md5);
+ ch.addData(cryptoText);
+ QString md5 = ch.result().toHex();
+
+ qDebug() << "md5" << md5;
+
+ QByteArray signText = QString("[%1][%2]").arg(serviceToken, md5).toUtf8();
+
+ QCryptographicHash sha(QCryptographicHash::Sha256);
+ sha.addData(signText);
+ QString shaText = sha.result().toHex();
+
+ qDebug() << "shaText" << shaText;
+
+ QVector keys{key};
+ QByteArray outSignText;
+ mCtx->sign(keys, signText, &outSignText, GPGME_SIG_MODE_NORMAL);
+ QByteArray outSignTextBase64 = outSignText.toBase64();
+
+ rapidjson::Value c, s, m, t;
+
+ rapidjson::Document doc;
+ doc.SetObject();
+
+ c.SetString(cryptoText.constData(), cryptoText.count());
+ auto m_byte_array = shaText.toUtf8();
+ m.SetString(m_byte_array.constData(), m_byte_array.count());
+ s.SetString(outSignTextBase64.constData(), outSignTextBase64.count());
+ auto t_byte_array = serviceToken.toUtf8();
+ t.SetString(t_byte_array.constData(), t_byte_array.count());
+
+ doc.AddMember("cryptoText", c, doc.GetAllocator());
+ doc.AddMember("sha", m, doc.GetAllocator());
+ doc.AddMember("sign", s, doc.GetAllocator());
+ doc.AddMember("serviceToken", t, doc.GetAllocator());
+
+ rapidjson::StringBuffer sb;
+ rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
+ doc.Accept(writer);
+
+ QByteArray postData(sb.GetString());
+ qDebug() << "postData" << QString::fromUtf8(postData);
+
+ QNetworkReply *reply = networkAccessManager->post(request, postData);
+
+ while (reply->isRunning()) {
+ QApplication::processEvents();
+ }
+
+ if (reply->error() == QNetworkReply::NoError) {
+ rapidjson::Document docReply;
+ docReply.Parse(reply->readAll().constData());
+ QString shortenText = docReply["shortenText"].GetString();
+ auto *dialog = new ShowCopyDialog(shortenText, this);
+ dialog->show();
+ } else {
+ QMessageBox::critical(this, tr("Error"), reply->errorString());
+ }
+
+
+}
+
/*
* Append the selected (not checked!) Key(s) To Textedit
*/
@@ -1077,14 +1258,14 @@ void MainWindow::slotOpenFile(QString &path) {
}
void MainWindow::slotVersionUpgrade(const QString &currentVersion, const QString &latestVersion) {
- if(currentVersion < latestVersion) {
+ if (currentVersion < latestVersion) {
QMessageBox::warning(this,
tr("Outdated Version"),
tr("This version(%1) is out of date, please update the latest version in time. ").arg(
currentVersion)
+ tr("You can download the latest version(%1) on Github Releases Page.<br/>").arg(
latestVersion));
- } else if(currentVersion > latestVersion) {
+ } else if (currentVersion > latestVersion) {
QMessageBox::warning(this,
tr("Unreleased Version"),
tr("This version(%1) has not been officially released and is not recommended for use in a production environment. <br/>").arg(
diff --git a/src/ui/widgets/EditorPage.cpp b/src/ui/widgets/EditorPage.cpp
index 05d5cbea..beb37b96 100644
--- a/src/ui/widgets/EditorPage.cpp
+++ b/src/ui/widgets/EditorPage.cpp
@@ -44,8 +44,6 @@ EditorPage::EditorPage(QString filePath, QWidget *parent) : QWidget(parent),
// Front in same width
this->setFont({"Courier"});
-
- connect(textPage, SIGNAL(textChanged()), this, SLOT(formatGpgHeader()));
}
const QString &EditorPage::getFilePath() const {
diff --git a/src/ui/widgets/InfoBoardWidget.cpp b/src/ui/widgets/InfoBoardWidget.cpp
index f26917a4..f64fda49 100644
--- a/src/ui/widgets/InfoBoardWidget.cpp
+++ b/src/ui/widgets/InfoBoardWidget.cpp
@@ -150,9 +150,12 @@ void InfoBoardWidget::associateTabWidget(QTabWidget *tab) {
connect(tab, SIGNAL(tabCloseRequested(int)), this, SLOT(slotReset()));
}
+
void InfoBoardWidget::addOptionalAction(const QString &name, const std::function<void()> &action) {
auto actionButton = new QPushButton(name);
infoBoard->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+ // set margin from surroundings
+ actionButton->setContentsMargins(5, 5, 5, 5);
actionButtonLayout->addWidget(actionButton);
connect(actionButton, &QPushButton::clicked, this, [=]() {
action();
diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp
index 3929868e..25f8870e 100644
--- a/src/ui/widgets/KeyList.cpp
+++ b/src/ui/widgets/KeyList.cpp
@@ -31,8 +31,7 @@ KeyList::KeyList(GpgME::GpgContext *ctx,
KeyListColumn::InfoType infoType,
QWidget *parent)
: QWidget(parent), mSelectType(selectType), mInfoType(infoType), appPath(qApp->applicationDirPath()),
- settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat)
-{
+ settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat) {
mCtx = ctx;
@@ -43,7 +42,7 @@ KeyList::KeyList(GpgME::GpgContext *ctx,
mKeyList->setShowGrid(false);
mKeyList->sortByColumn(2, Qt::AscendingOrder);
mKeyList->setSelectionBehavior(QAbstractItemView::SelectRows);
- mKeyList->setSelectionMode( QAbstractItemView::SingleSelection );
+ mKeyList->setSelectionMode(QAbstractItemView::SingleSelection);
// tableitems not editable
mKeyList->setEditTriggers(QAbstractItemView::NoEditTriggers);
@@ -54,22 +53,22 @@ KeyList::KeyList(GpgME::GpgContext *ctx,
mKeyList->setAlternatingRowColors(true);
// Hidden Column For Purpose
- if(!(mInfoType & KeyListColumn::TYPE)) {
+ if (!(mInfoType & KeyListColumn::TYPE)) {
mKeyList->setColumnHidden(1, true);
}
- if(!(mInfoType & KeyListColumn::NAME)) {
+ if (!(mInfoType & KeyListColumn::NAME)) {
mKeyList->setColumnHidden(2, true);
}
- if(!(mInfoType & KeyListColumn::EmailAddress)) {
+ if (!(mInfoType & KeyListColumn::EmailAddress)) {
mKeyList->setColumnHidden(3, true);
}
- if(!(mInfoType & KeyListColumn::Usage)) {
+ if (!(mInfoType & KeyListColumn::Usage)) {
mKeyList->setColumnHidden(4, true);
}
- if(!(mInfoType & KeyListColumn::Validity)) {
+ if (!(mInfoType & KeyListColumn::Validity)) {
mKeyList->setColumnHidden(5, true);
}
- if(!(mInfoType & KeyListColumn::FingerPrint)) {
+ if (!(mInfoType & KeyListColumn::FingerPrint)) {
mKeyList->setColumnHidden(6, true);
}
@@ -95,8 +94,7 @@ KeyList::KeyList(GpgME::GpgContext *ctx,
slotRefresh();
}
-void KeyList::slotRefresh()
-{
+void KeyList::slotRefresh() {
QStringList *keyList;
keyList = getChecked();
// while filling the table, sort enabled causes errors
@@ -110,21 +108,21 @@ void KeyList::slotRefresh()
int row_count = 0;
while (it != keys.end()) {
- if(mFilter != nullptr) {
- if(!mFilter(*it)) {
+ if (mFilter != nullptr) {
+ if (!mFilter(*it)) {
it = keys.erase(it);
continue;
}
}
- if(!excluded_key_ids.isEmpty()){
+ if (!excluded_key_ids.isEmpty()) {
auto iterator = std::find_if(excluded_key_ids.begin(), excluded_key_ids.end(),
- [it] (const auto &key_id) -> bool {
- if(it->id == key_id) return true;
- else return false;
- });
+ [it](const auto &key_id) -> bool {
+ if (it->id == key_id) return true;
+ else return false;
+ });
- if(iterator != excluded_key_ids.end()) {
+ if (iterator != excluded_key_ids.end()) {
it = keys.erase(it);
continue;
}
@@ -161,10 +159,10 @@ void KeyList::slotRefresh()
type_steam << "pub";
}
- if(it->is_private_key && !it->has_master_key) {
+ if (it->is_private_key && !it->has_master_key) {
type_steam << "#";
}
- auto* tmp1 = new QTableWidgetItem(type_str);
+ auto *tmp1 = new QTableWidgetItem(type_str);
mKeyList->setItem(row_index, 1, tmp1);
auto *tmp2 = new QTableWidgetItem(it->name);
@@ -177,13 +175,13 @@ void KeyList::slotRefresh()
QString usage;
QTextStream usage_steam(&usage);
- if(GpgME::GpgContext::checkIfKeyCanCert(*it))
+ if (GpgME::GpgContext::checkIfKeyCanCert(*it))
usage_steam << "C";
- if(GpgME::GpgContext::checkIfKeyCanEncr(*it))
+ if (GpgME::GpgContext::checkIfKeyCanEncr(*it))
usage_steam << "E";
- if(GpgME::GpgContext::checkIfKeyCanSign(*it))
+ if (GpgME::GpgContext::checkIfKeyCanSign(*it))
usage_steam << "S";
- if(GpgME::GpgContext::checkIfKeyCanAuth(*it))
+ if (GpgME::GpgContext::checkIfKeyCanAuth(*it))
usage_steam << "A";
auto *temp_usage = new QTableWidgetItem(usage);
@@ -199,7 +197,7 @@ void KeyList::slotRefresh()
mKeyList->setItem(row_index, 6, temp_fpr);
// strike out expired keys
- if(it->expired || it->revoked) {
+ if (it->expired || it->revoked) {
QFont strike = tmp2->font();
strike.setStrikeOut(true);
tmp0->setFont(strike);
@@ -218,8 +216,7 @@ void KeyList::slotRefresh()
setChecked(keyList);
}
-QStringList *KeyList::getChecked()
-{
+QStringList *KeyList::getChecked() {
auto *ret = new QStringList();
for (int i = 0; i < mKeyList->rowCount(); i++) {
if (mKeyList->item(i, 0)->checkState() == Qt::Checked) {
@@ -229,19 +226,17 @@ QStringList *KeyList::getChecked()
return ret;
}
-QStringList *KeyList::getAllPrivateKeys()
-{
+QStringList *KeyList::getAllPrivateKeys() {
auto *ret = new QStringList();
for (int i = 0; i < mKeyList->rowCount(); i++) {
- if (mKeyList->item(i, 1)) {
+ if (mKeyList->item(i, 1) && buffered_keys[i].is_private_key) {
*ret << buffered_keys[i].id;
}
}
return ret;
}
-QStringList *KeyList::getPrivateChecked()
-{
+QStringList *KeyList::getPrivateChecked() {
auto *ret = new QStringList();
for (int i = 0; i < mKeyList->rowCount(); i++) {
if ((mKeyList->item(i, 0)->checkState() == Qt::Checked) && (mKeyList->item(i, 1))) {
@@ -251,19 +246,17 @@ QStringList *KeyList::getPrivateChecked()
return ret;
}
-void KeyList::setChecked(QStringList *keyIds)
-{
+void KeyList::setChecked(QStringList *keyIds) {
if (!keyIds->isEmpty()) {
for (int i = 0; i < mKeyList->rowCount(); i++) {
- if (keyIds->contains(buffered_keys[i].id)) {
+ if (keyIds->contains(buffered_keys[i].id)) {
mKeyList->item(i, 0)->setCheckState(Qt::Checked);
}
}
}
}
-QStringList *KeyList::getSelected()
-{
+QStringList *KeyList::getSelected() {
auto *ret = new QStringList();
for (int i = 0; i < mKeyList->rowCount(); i++) {
@@ -274,47 +267,42 @@ QStringList *KeyList::getSelected()
return ret;
}
-[[maybe_unused]] bool KeyList::containsPrivateKeys()
-{
+[[maybe_unused]] bool KeyList::containsPrivateKeys() {
for (int i = 0; i < mKeyList->rowCount(); i++) {
if (mKeyList->item(i, 1)) {
- return true;
+ return true;
}
}
return false;
}
-void KeyList::setColumnWidth(int row, int size)
-{
+void KeyList::setColumnWidth(int row, int size) {
mKeyList->setColumnWidth(row, size);
}
-void KeyList::contextMenuEvent(QContextMenuEvent *event)
-{
+void KeyList::contextMenuEvent(QContextMenuEvent *event) {
if (mKeyList->selectedItems().length() > 0) {
popupMenu->exec(event->globalPos());
}
}
-void KeyList::addSeparator()
-{
+void KeyList::addSeparator() {
popupMenu->addSeparator();
}
-void KeyList::addMenuAction(QAction *act)
-{
+void KeyList::addMenuAction(QAction *act) {
popupMenu->addAction(act);
}
-void KeyList::dropEvent(QDropEvent* event)
-{
+void KeyList::dropEvent(QDropEvent *event) {
auto *dialog = new QDialog();
dialog->setWindowTitle(tr("Import Keys"));
QLabel *label;
- label = new QLabel(tr("You've dropped something on the table.\n GpgFrontend will now try to import key(s).")+"\n");
+ label = new QLabel(
+ tr("You've dropped something on the table.\n GpgFrontend will now try to import key(s).") + "\n");
// "always import keys"-CheckBox
auto *checkBox = new QCheckBox(tr("Always import without bothering."));
@@ -332,56 +320,50 @@ void KeyList::dropEvent(QDropEvent* event)
dialog->setLayout(vbox);
- if (settings.value("general/confirmImportKeys",Qt::Checked).toBool())
- {
+ if (settings.value("general/confirmImportKeys", Qt::Checked).toBool()) {
dialog->exec();
if (dialog->result() == QDialog::Rejected) {
return;
}
- if (checkBox->isChecked()){
- settings.setValue("general/confirmImportKeys", false);
+ if (checkBox->isChecked()) {
+ settings.setValue("general/confirmImportKeys", false);
} else {
settings.setValue("general/confirmImportKeys", true);
}
}
- if (event->mimeData()->hasUrls())
- {
- for (const QUrl& tmp : event->mimeData()->urls())
- {
- QFile file;
- file.setFileName(tmp.toLocalFile());
- if (!file.open(QIODevice::ReadOnly)) {
- qDebug() << tr("Couldn't Open File: ") + tmp.toString();
- }
- QByteArray inBuffer = file.readAll();
- this->importKeys(inBuffer);
- file.close();
- }
- } else {
- QByteArray inBuffer(event->mimeData()->text().toUtf8());
+ if (event->mimeData()->hasUrls()) {
+ for (const QUrl &tmp : event->mimeData()->urls()) {
+ QFile file;
+ file.setFileName(tmp.toLocalFile());
+ if (!file.open(QIODevice::ReadOnly)) {
+ qDebug() << tr("Couldn't Open File: ") + tmp.toString();
+ }
+ QByteArray inBuffer = file.readAll();
this->importKeys(inBuffer);
- }
+ file.close();
+ }
+ } else {
+ QByteArray inBuffer(event->mimeData()->text().toUtf8());
+ this->importKeys(inBuffer);
+ }
}
-void KeyList::dragEnterEvent(QDragEnterEvent *event)
-{
+void KeyList::dragEnterEvent(QDragEnterEvent *event) {
event->acceptProposedAction();
}
/** set background color for Keys and put them to top
*
*/
-[[maybe_unused]] void KeyList::markKeys(QStringList *keyIds)
-{
- foreach(QString id, *keyIds) {
- qDebug() << "marked: " << id;
- }
+[[maybe_unused]] void KeyList::markKeys(QStringList *keyIds) {
+ foreach(QString id, *keyIds) {
+ qDebug() << "marked: " << id;
+ }
}
-void KeyList::importKeys(QByteArray inBuffer)
-{
+void KeyList::importKeys(QByteArray inBuffer) {
GpgImportInformation result = mCtx->importKey(std::move(inBuffer));
new KeyImportDetailDialog(mCtx, result, false, this);
}
@@ -397,7 +379,7 @@ void KeyList::getCheckedKeys(QVector<GpgKey> &keys) {
void KeyList::setExcludeKeys(std::initializer_list<QString> key_ids) {
excluded_key_ids.clear();
- for(auto &key_id : key_ids) {
+ for (auto &key_id : key_ids) {
excluded_key_ids.push_back(key_id);
}
}
@@ -407,7 +389,7 @@ void KeyList::setFilter(std::function<bool(const GpgKey &)> filter) {
}
void KeyList::slotDoubleClicked(const QModelIndex &index) {
- if(mAction != nullptr) {
+ if (mAction != nullptr) {
const auto &key = mCtx->getKeyById(buffered_keys[index.row()].id);
mAction(key, this);
}