aboutsummaryrefslogtreecommitdiffstats
path: root/src/ui/KeyServerImportDialog.cpp
diff options
context:
space:
mode:
authorSaturneric <[email protected]>2021-05-12 02:14:58 +0000
committerSaturneric <[email protected]>2021-05-12 02:14:58 +0000
commit26691b14d7d3294769c1cb0d0e099efd75dcc6c6 (patch)
tree7e16cb949955e635bada530ba7fd23a43ef8e4bb /src/ui/KeyServerImportDialog.cpp
parentSrouce Files Tidy and Reform (diff)
downloadGpgFrontend-26691b14d7d3294769c1cb0d0e099efd75dcc6c6.tar.gz
GpgFrontend-26691b14d7d3294769c1cb0d0e099efd75dcc6c6.zip
File Structure Modified.
Change Headers and Source Files Name. Modified CMake Structure.
Diffstat (limited to 'src/ui/KeyServerImportDialog.cpp')
-rw-r--r--src/ui/KeyServerImportDialog.cpp302
1 files changed, 302 insertions, 0 deletions
diff --git a/src/ui/KeyServerImportDialog.cpp b/src/ui/KeyServerImportDialog.cpp
new file mode 100644
index 00000000..3f3ed95c
--- /dev/null
+++ b/src/ui/KeyServerImportDialog.cpp
@@ -0,0 +1,302 @@
+/*
+ *
+ * keyserverimportdialog.cpp
+ *
+ * Copyright 2008 gpg4usb-team <[email protected]>
+ *
+ * This file is part of gpg4usb.
+ *
+ * Gpg4usb 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.
+ *
+ * Gpg4usb 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 gpg4usb. If not, see <http://www.gnu.org/licenses/>
+ */
+
+#include "ui/KeyServerImportDialog.h"
+
+#include <utility>
+
+KeyServerImportDialog::KeyServerImportDialog(GpgME::GpgContext *ctx, KeyList *keyList, QWidget *parent)
+ : QDialog(parent) {
+ mCtx = ctx;
+ mKeyList = keyList;
+ // Buttons
+ closeButton = createButton(tr("&Close"), SLOT(close()));
+ importButton = createButton(tr("&Import"), SLOT(slotImport()));
+ searchButton = createButton(tr("&Search"), SLOT(slotSearch()));
+
+ // Line edit for search string
+ searchLabel = new QLabel(tr("Search string:"));
+ searchLineEdit = new QLineEdit();
+
+ // combobox for keyserverlist
+ keyServerLabel = new QLabel(tr("Keyserver:"));
+ keyServerComboBox = createComboBox();
+
+ // table containing the keys found
+ createKeysTable();
+ message = new QLabel;
+ icon = new QLabel;
+
+ // Layout for messagebox
+ auto *messageLayout = new QHBoxLayout;
+ messageLayout->addWidget(icon);
+ messageLayout->addWidget(message);
+ messageLayout->addStretch();
+
+ // Layout for import and close button
+ auto *buttonsLayout = new QHBoxLayout;
+ buttonsLayout->addStretch();
+ buttonsLayout->addWidget(importButton);
+ buttonsLayout->addWidget(closeButton);
+
+ auto *mainLayout = new QGridLayout;
+ mainLayout->addWidget(searchLabel, 1, 0);
+ mainLayout->addWidget(searchLineEdit, 1, 1);
+ mainLayout->addWidget(searchButton, 1, 2);
+ mainLayout->addWidget(keyServerLabel, 2, 0);
+ mainLayout->addWidget(keyServerComboBox, 2, 1);
+ mainLayout->addWidget(keysTable, 3, 0, 1, 3);
+ mainLayout->addLayout(messageLayout, 4, 0, 1, 3);
+ mainLayout->addLayout(buttonsLayout, 5, 0, 1, 3);
+
+ this->setLayout(mainLayout);
+ this->setWindowTitle(tr("Import Keys from Keyserver"));
+ this->resize(700, 300);
+ this->setModal(true);
+}
+
+QPushButton *KeyServerImportDialog::createButton(const QString &text, const char *member) {
+ auto *button = new QPushButton(text);
+ connect(button, SIGNAL(clicked()), this, member);
+ return button;
+}
+
+QComboBox *KeyServerImportDialog::createComboBox() {
+ auto *comboBox = new QComboBox;
+ comboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+
+ // Read keylist from ini-file and fill it into combobox
+ QSettings settings;
+ comboBox->addItems(settings.value("keyserver/keyServerList").toStringList());
+
+ // set default keyserver in combobox
+ QString keyserver = settings.value("keyserver/defaultKeyServer").toString();
+ comboBox->setCurrentIndex(comboBox->findText(keyserver));
+
+ return comboBox;
+}
+
+void KeyServerImportDialog::createKeysTable() {
+ keysTable = new QTableWidget();
+ keysTable->setColumnCount(4);
+
+ // always a whole row is marked
+ keysTable->setSelectionBehavior(QAbstractItemView::SelectRows);
+ keysTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
+
+ // Make just one row selectable
+ keysTable->setSelectionMode(QAbstractItemView::SingleSelection);
+
+ QStringList labels;
+ labels << tr("UID") << tr("Creation date") << tr("KeyID") << tr("Tag");
+ keysTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
+ keysTable->setHorizontalHeaderLabels(labels);
+ keysTable->verticalHeader()->hide();
+
+ connect(keysTable, SIGNAL(cellActivated(int, int)),
+ this, SLOT(slotImport()));
+}
+
+void KeyServerImportDialog::setMessage(const QString &text, bool error) {
+ message->setText(text);
+ if (error) {
+ QIcon undoicon = QIcon::fromTheme("dialog-error");
+ QPixmap pixmap = undoicon.pixmap(QSize(32, 32), QIcon::Normal, QIcon::On);
+ icon->setPixmap(pixmap);
+ } else {
+ QIcon undoicon = QIcon::fromTheme("dialog-information");
+ QPixmap pixmap = undoicon.pixmap(QSize(32, 32), QIcon::Normal, QIcon::On);
+ icon->setPixmap(pixmap);
+ }
+}
+
+void KeyServerImportDialog::slotSearch() {
+ QUrl urlFromRemote = keyServerComboBox->currentText() + ":11371/pks/lookup?search=" + searchLineEdit->text() +
+ "&op=index&options=mr";
+ qnam = new QNetworkAccessManager(this);
+ QNetworkReply *reply = qnam->get(QNetworkRequest(urlFromRemote));
+ connect(reply, SIGNAL(finished()),
+ this, SLOT(slotSearchFinished()));
+}
+
+void KeyServerImportDialog::slotSearchFinished() {
+ auto *reply = qobject_cast<QNetworkReply *>(sender());
+
+ keysTable->clearContents();
+ keysTable->setRowCount(0);
+ QString firstLine = QString(reply->readLine(1024));
+
+ QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
+ if (reply->error()) {
+ setMessage(tr("Couldn't contact keyserver!"), true);
+ //setMessage(reply->error());
+ qDebug() << reply->error();
+ }
+ if (firstLine.contains("Error")) {
+ QString text = QString(reply->readLine(1024));
+ if (text.contains("Too many responses")) {
+ setMessage(tr("Too many responses from keyserver!"), true);
+ } else if (text.contains("No keys found")) {
+ // if string looks like hex string, search again with 0x prepended
+ QRegExp rx("[0-9A-Fa-f]*");
+ QString query = searchLineEdit->text();
+ if (rx.exactMatch(query)) {
+ setMessage(tr("No keys found, input may be kexId, retrying search with 0x."), true);
+ searchLineEdit->setText(query.prepend("0x"));
+ this->slotSearch();
+ } else {
+ setMessage(tr("No keys found containing the search string!"), true);
+ }
+ } else if (text.contains("Insufficiently specific words")) {
+ setMessage(tr("Insufficiently specific search string!"), true);
+ } else {
+ setMessage(text, true);
+ }
+ } else {
+ int row = 0;
+ char buff[1024];
+ bool strikeout = false;
+ while (reply->readLine(buff, sizeof(buff)) != -1) {
+ QString decoded = QString::fromUtf8(QByteArray::fromPercentEncoding(buff));
+ QStringList line = decoded.split(":");
+
+ //TODO: have a look at two following pub lines
+ if (line[0] == "pub") {
+ strikeout = false;
+
+ QString flags = line[line.size() - 1];
+
+ keysTable->setRowCount(row + 1);
+
+ // flags can be "d" for disabled, "r" for revoked
+ // or "e" for expired
+ if (flags.contains("r") or flags.contains("d") or flags.contains("e")) {
+ strikeout = true;
+ if (flags.contains("e")) {
+ keysTable->setItem(row, 3, new QTableWidgetItem(QString("expired")));
+ }
+ if (flags.contains("r")) {
+ keysTable->setItem(row, 3, new QTableWidgetItem(QString(tr("revoked"))));
+ }
+ if (flags.contains("d")) {
+ keysTable->setItem(row, 3, new QTableWidgetItem(QString(tr("disabled"))));
+ }
+ }
+
+ QStringList line2 = QString(reply->readLine()).split(":");
+
+ auto *uid = new QTableWidgetItem();
+ if (line2.size() > 1) {
+ uid->setText(line2[1]);
+ keysTable->setItem(row, 0, uid);
+ }
+ auto *creationdate = new QTableWidgetItem(
+ QDateTime::fromTime_t(line[4].toInt()).toString("dd. MMM. yyyy"));
+ keysTable->setItem(row, 1, creationdate);
+ auto *keyid = new QTableWidgetItem(line[1]);
+ keysTable->setItem(row, 2, keyid);
+ if (strikeout) {
+ QFont strike = uid->font();
+ strike.setStrikeOut(true);
+ uid->setFont(strike);
+ creationdate->setFont(strike);
+ keyid->setFont(strike);
+ }
+ row++;
+ } else {
+ if (line[0] == "uid") {
+ QStringList l;
+ int height = keysTable->rowHeight(row - 1);
+ keysTable->setRowHeight(row - 1, height + 16);
+ QString tmp = keysTable->item(row - 1, 0)->text();
+ tmp.append(QString("\n") + line[1]);
+ auto *tmp1 = new QTableWidgetItem(tmp);
+ keysTable->setItem(row - 1, 0, tmp1);
+ if (strikeout) {
+ QFont strike = tmp1->font();
+ strike.setStrikeOut(true);
+ tmp1->setFont(strike);
+ }
+ }
+ }
+ setMessage(tr("%1 keys found. Doubleclick a key to import it.").arg(row), false);
+ }
+ keysTable->resizeColumnsToContents();
+ }
+ reply->deleteLater();
+}
+
+void KeyServerImportDialog::slotImport() {
+ if (keysTable->currentRow() > -1) {
+ QString keyid = keysTable->item(keysTable->currentRow(), 2)->text();
+ slotImport(QStringList(keyid), keyServerComboBox->currentText());
+ }
+}
+
+void KeyServerImportDialog::slotImport(QStringList keyIds) {
+ QSettings settings;
+ QString keyserver = settings.value("keyserver/defaultKeyServer").toString();;
+ slotImport(std::move(keyIds), QUrl(keyserver));
+}
+
+
+void KeyServerImportDialog::slotImport(QStringList keyIds, const QUrl &keyServerUrl) {
+ foreach(QString keyId, keyIds) {
+ QUrl reqUrl(
+ keyServerUrl.scheme() + "://" + keyServerUrl.host() + ":11371/pks/lookup?op=get&search=0x" + keyId +
+ "&options=mr");
+ //qDebug() << "req to " << reqUrl;
+ qnam = new QNetworkAccessManager(this);
+ QNetworkReply *reply = qnam->get(QNetworkRequest(reqUrl));
+ connect(reply, SIGNAL(finished()),
+ this, SLOT(slotImportFinished()));
+ }
+}
+
+void KeyServerImportDialog::slotImportFinished() {
+ auto *reply = qobject_cast<QNetworkReply *>(sender());
+
+ QByteArray key = reply->readAll();
+
+ QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
+ if (reply->error()) {
+ setMessage(tr("Error while contacting keyserver!"), true);
+ return;
+ }
+ this->importKeys(key.constData());
+ setMessage(tr("Key imported"), false);
+
+ // Add keyserver to list in config-file, if it isn't contained
+ QSettings settings;
+ QStringList keyServerList = settings.value("keyserver/keyServerList").toStringList();
+ if (!keyServerList.contains(keyServerComboBox->currentText())) {
+ keyServerList.append(keyServerComboBox->currentText());
+ settings.setValue("keyserver/keyServerList", keyServerList);
+ }
+ reply->deleteLater();
+ reply = nullptr;
+}
+
+void KeyServerImportDialog::importKeys(QByteArray inBuffer) {
+ GpgImportInformation result = mCtx->importKey(std::move(inBuffer));
+ new KeyImportDetailDialog(mCtx, result, this);
+}