aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorubbo <ubbo@34ebc366-c3a9-4b3c-9f84-69acf7962910>2012-08-03 22:46:46 +0000
committerubbo <ubbo@34ebc366-c3a9-4b3c-9f84-69acf7962910>2012-08-03 22:46:46 +0000
commit57eb187661072f51c1facf0970a2d70445fd242c (patch)
tree71ba2b42ef2e176332ee4aefaa3d645b29123d52
parentappend selected keys works (diff)
downloadgpg4usb-57eb187661072f51c1facf0970a2d70445fd242c.tar.gz
gpg4usb-57eb187661072f51c1facf0970a2d70445fd242c.zip
import from textedit works
git-svn-id: http://cpunk.de/svn/src/gpg4usb/branches/0.3.2-mac@937 34ebc366-c3a9-4b3c-9f84-69acf7962910
-rw-r--r--gpg4usb.pro6
-rw-r--r--gpgcontext.cpp4
-rw-r--r--gpgcontext.h2
-rw-r--r--kgpg/transactions/kgpgimport.cpp295
-rw-r--r--kgpg/transactions/kgpgimport.h129
-rw-r--r--mainwindow.cpp67
-rw-r--r--mainwindow.h3
7 files changed, 503 insertions, 3 deletions
diff --git a/gpg4usb.pro b/gpg4usb.pro
index 0a831af..826df2a 100644
--- a/gpg4usb.pro
+++ b/gpg4usb.pro
@@ -67,7 +67,8 @@ HEADERS += attachments.h \
kgpg/transactions/kgpgtextorfiletransaction.h \
kgpg/transactions/kgpgencrypt.h \
kgpg/transactions/kgpgdecrypt.h \
- kgpg/transactions/kgpgexport.h
+ kgpg/transactions/kgpgexport.h \
+ kgpg/transactions/kgpgimport.h
SOURCES += attachments.cpp \
@@ -118,7 +119,8 @@ SOURCES += attachments.cpp \
kgpg/transactions/kgpgtextorfiletransaction.cpp \
kgpg/transactions/kgpgencrypt.cpp \
kgpg/transactions/kgpgdecrypt.cpp \
- kgpg/transactions/kgpgexport.cpp
+ kgpg/transactions/kgpgexport.cpp \
+ kgpg/transactions/kgpgimport.cpp
RC_FILE = gpg4usb.rc
diff --git a/gpgcontext.cpp b/gpgcontext.cpp
index a6dec21..677c2c5 100644
--- a/gpgcontext.cpp
+++ b/gpgcontext.cpp
@@ -770,6 +770,10 @@ QString GpgContext::getGpgmeVersion() {
return QString(gpgme_check_version(NULL));
}
+void GpgContext::emitKeyDBChanged() {
+ emit keyDBChanged();
+}
+
}
diff --git a/gpgcontext.h b/gpgcontext.h
index ba4cf67..388c957 100644
--- a/gpgcontext.h
+++ b/gpgcontext.h
@@ -135,6 +135,8 @@ public:
GpgKey getKeyByFpr(QString fpr);
GpgKey getKeyById(QString id);
+ void emitKeyDBChanged();
+
static QString gpgErrString(gpgme_error_t err);
static QString getGpgmeVersion();
diff --git a/kgpg/transactions/kgpgimport.cpp b/kgpg/transactions/kgpgimport.cpp
new file mode 100644
index 0000000..4a3041c
--- /dev/null
+++ b/kgpg/transactions/kgpgimport.cpp
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2008,2009,2010,2012 Rolf Eike Beer <[email protected]>
+ */
+
+/***************************************************************************
+ * *
+ * This program 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "kgpgimport.h"
+
+//#include "model/kgpgitemmodel.h"
+#include "../core/KGpgKeyNode.h"
+
+#include <QDebug>
+//#include <KLocale>
+
+KGpgImport::KGpgImport(QObject *parent, const QString &text)
+ : KGpgTextOrFileTransaction(parent, text, true)
+{
+}
+
+KGpgImport::KGpgImport(QObject *parent, const QList<QUrl> &files)
+ : KGpgTextOrFileTransaction(parent, files, true)
+{
+}
+
+KGpgImport::~KGpgImport()
+{
+}
+
+QStringList
+KGpgImport::command() const
+{
+ QStringList ret;
+
+ ret << QLatin1String( "--import" ) << QLatin1String( "--allow-secret-key-import" );
+
+ return ret;
+}
+
+QStringList
+KGpgImport::getImportedKeys() const
+{
+ QStringList res;
+
+ foreach (const QString &str, getMessages())
+ if (str.startsWith(QLatin1String("[GNUPG:] IMPORTED ")))
+ res << str.mid(18);
+
+ return res;
+}
+
+QStringList
+KGpgImport::getImportedIds(const QStringList &log, const int reason)
+{
+ QStringList res;
+
+ foreach (const QString &str, log) {
+ if (!str.startsWith(QLatin1String("[GNUPG:] IMPORT_OK ")))
+ continue;
+
+ QString tmpstr(str.mid(19).simplified());
+
+ int space = tmpstr.indexOf(QLatin1Char( ' ' ));
+ if (space <= 0) {
+ qDebug() << __LINE__ << "invalid format:" << str;
+ continue;
+ }
+
+ bool ok;
+ unsigned char code = tmpstr.left(space).toUInt(&ok);
+ if (!ok) {
+ qDebug() << __LINE__ << "invalid format:" << str << space << tmpstr.left(space - 1);
+ continue;
+ }
+
+ if ((reason == -1) || ((reason == 0) && (code == 0)) || ((reason & code) != 0))
+ res << tmpstr.mid(space + 1);
+ }
+
+ return res;
+}
+
+QStringList
+KGpgImport::getImportedIds(const int reason) const
+{
+ return getImportedIds(getMessages(), reason);
+}
+
+QString
+KGpgImport::getImportMessage() const
+{
+ return getImportMessage(getMessages());
+}
+
+QString
+KGpgImport::getImportMessage(const QStringList &log)
+{
+#define RESULT_PARTS 14
+ unsigned long rcode[RESULT_PARTS];
+ unsigned int i = 0;
+ int line = 0;
+ bool fine;
+
+ memset(rcode, 0, sizeof(rcode));
+
+ foreach (const QString &str, log) {
+ line++;
+ if (!str.startsWith(QLatin1String("[GNUPG:] IMPORT_RES ")))
+ continue;
+
+ const QStringList rstr(str.mid(20).simplified().split(QLatin1Char( ' ' )));
+
+ fine = (rstr.count() == RESULT_PARTS);
+
+ i = 0;
+ while (fine && (i < RESULT_PARTS)) {
+ rcode[i] += rstr.at(i).toULong(&fine);
+ i++;
+ }
+
+ if (!fine)
+ return tr("The import result string has an unsupported format in line %1.<br />Please see the detailed log for more information.").arg(line);
+ }
+
+ fine = false;
+ i = 0;
+ while (!fine && (i < RESULT_PARTS)) {
+ fine = (rcode[i] != 0);
+ i++;
+ }
+
+ if (!fine)
+ return tr("No key imported.<br />Please see the detailed log for more information.");
+
+ QString resultMessage(tr("<qt>%1 key processed.</qt>", "<qt>%1 keys processed.</qt>", rcode[0]));
+
+ if (rcode[1])
+ resultMessage += tr("<qt><br />One key without ID.</qt>", "<qt><br />%1 keys without ID.</qt>", rcode[1]);
+ if (rcode[2])
+ resultMessage += tr("<qt><br /><b>One key imported:</b></qt>", "<qt><br /><b>%1 keys imported:</b></qt>", rcode[2]);
+ if (rcode[3])
+ resultMessage += tr("<qt><br />One RSA key imported.</qt>", "<qt><br />%1 RSA keys imported.</qt>", rcode[3]);
+ if (rcode[4])
+ resultMessage += tr("<qt><br />One key unchanged.</qt>", "<qt><br />%1 keys unchanged.</qt>", rcode[4]);
+ if (rcode[5])
+ resultMessage += tr("<qt><br />One user ID imported.</qt>", "<qt><br />%1 user IDs imported.</qt>", rcode[5]);
+ if (rcode[6])
+ resultMessage += tr("<qt><br />One subkey imported.</qt>", "<qt><br />%1 subkeys imported.</qt>", rcode[6]);
+ if (rcode[7])
+ resultMessage += tr("<qt><br />One signature imported.</qt>", "<qt><br />%1 signatures imported.</qt>", rcode[7]);
+ if (rcode[8])
+ resultMessage += tr("<qt><br />One revocation certificate imported.</qt>", "<qt><br />%1 revocation certificates imported.</qt>", rcode[8]);
+ if (rcode[9])
+ resultMessage += tr("<qt><br />One secret key processed.</qt>", "<qt><br />%1 secret keys processed.</qt>", rcode[9]);
+ if (rcode[10])
+ resultMessage += tr("<qt><br /><b>One secret key imported.</b></qt>", "<qt><br /><b>%1 secret keys imported.</b></qt>", rcode[10]);
+ if (rcode[11])
+ resultMessage += tr("<qt><br />One secret key unchanged.</qt>", "<qt><br />%1 secret keys unchanged.</qt>", rcode[11]);
+ if (rcode[12])
+ resultMessage += tr("<qt><br />One secret key not imported.</qt>", "<qt><br />%1 secret keys not imported.</qt>", rcode[12]);
+
+ if (rcode[9])
+ resultMessage += tr("<qt><br /><b>You have imported a secret key.</b> <br />"
+ "Please note that imported secret keys are not trusted by default.<br />"
+ "To fully use this secret key for signing and encryption, you must edit the key (double click on it) and set its trust to Full or Ultimate.</qt>");
+
+ return resultMessage;
+}
+
+/*static QString
+beautifyKeyList(const QStringList &keyIds, const KGpgItemModel *model)
+{
+ QString result;
+
+ result.append(QLatin1String("\n"));
+ if (model == NULL) {
+ result.append(QLatin1String(" ") + keyIds.join(QLatin1String("\n ")));
+ } else {
+ foreach (const QString &changed, keyIds) {
+ const KGpgKeyNode *node = model->findKeyNode(changed);
+ QString line;
+
+ if (node == NULL) {
+ line = changed;
+ } else {
+ if (node->getEmail().isEmpty())
+ line = trc("ID: Name", "%1: %2", node->getFingerprint(), node->getName());
+ else
+ line = trc("ID: Name <Email>", "%1: %2 &lt;%3&gt;", node->getFingerprint(), node->getName(), node->getEmail());
+ }
+
+ result.append(QLatin1String(" ") + line + QLatin1String("\n"));
+ }
+ }
+
+ return result;
+}*/
+
+QString
+KGpgImport::getDetailedImportMessage(const QStringList &log, const KGpgItemModel *model)
+{
+ QString result;
+ QMap<QString, unsigned int> resultcodes;
+
+ foreach (const QString &keyresult, log) {
+ if (!keyresult.startsWith(QLatin1String("[GNUPG:] IMPORT_OK ")))
+ continue;
+
+ QStringList rc(keyresult.mid(19).split(QLatin1Char( ' ' )));
+ if (rc.count() < 2) {
+ qDebug() << "unexpected syntax:" << keyresult;
+ continue;
+ }
+
+ resultcodes[rc.at(1)] = rc.at(0).toUInt();
+ }
+
+ QMap<QString, unsigned int>::const_iterator iterend = resultcodes.constEnd();
+
+ for (unsigned int flag = 1; flag <= 16; flag <<= 1) {
+ QStringList thischanged;
+
+ for (QMap<QString, unsigned int>::const_iterator iter = resultcodes.constBegin(); iter != iterend; ++iter) {
+ if (iter.value() & flag)
+ thischanged << iter.key();
+ }
+
+ if (thischanged.isEmpty())
+ continue;
+
+ switch (flag) {
+ case 1:
+ result.append(tr("New Key", "New Keys", thischanged.count()));
+ break;
+ case 2:
+ result.append(tr("Key with new User Id", "Keys with new User Ids", thischanged.count()));
+ break;
+ case 4:
+ result.append(tr("Key with new Signatures", "Keys with new Signatures", thischanged.count()));
+ break;
+ case 8:
+ result.append(tr("Key with new Subkeys", "Keys with new Subkeys", thischanged.count()));
+ break;
+ case 16:
+ result.append(tr("New Private Key", "New Private Keys", thischanged.count()));
+ break;
+ default:
+ Q_ASSERT(flag == 1);
+ }
+
+// result.append(beautifyKeyList(thischanged, model));
+ result.append(QLatin1String("\n\n"));
+ }
+
+ QStringList unchanged(resultcodes.keys(0));
+
+ if (unchanged.isEmpty()) {
+ // remove empty line at end
+ result.chop(1);
+ } else {
+ result.append(tr("Unchanged Key", "Unchanged Keys", unchanged.count()));
+// result.append(beautifyKeyList(unchanged, model));
+ result.append(QLatin1String("\n"));
+ }
+
+ return result;
+}
+
+int
+KGpgImport::isKey(const QString &text, const bool incomplete)
+{
+ int markpos = text.indexOf(QLatin1String("-----BEGIN PGP PUBLIC KEY BLOCK-----"));
+ if (markpos >= 0) {
+ markpos = text.indexOf(QLatin1String("-----END PGP PUBLIC KEY BLOCK-----"), markpos);
+ return ((markpos > 0) || incomplete) ? 1 : 0;
+ }
+
+ markpos = text.indexOf(QLatin1String("-----BEGIN PGP PRIVATE KEY BLOCK-----"));
+ if (markpos < 0)
+ return 0;
+
+ markpos = text.indexOf(QLatin1String("-----END PGP PRIVATE KEY BLOCK-----"), markpos);
+ if ((markpos < 0) && !incomplete)
+ return 0;
+
+ return 2;
+}
+
+//#include "kgpgimport.moc"
diff --git a/kgpg/transactions/kgpgimport.h b/kgpg/transactions/kgpgimport.h
new file mode 100644
index 0000000..7fe6deb
--- /dev/null
+++ b/kgpg/transactions/kgpgimport.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2008,2009,2010 Rolf Eike Beer <[email protected]>
+ */
+
+/***************************************************************************
+ * *
+ * This program 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 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef KGPGIMPORT_H
+#define KGPGIMPORT_H
+
+#include <QObject>
+#include <QList>
+#include <QString>
+#include <QStringList>
+
+#include <QUrl>
+
+#include "kgpgtextorfiletransaction.h"
+
+class KGpgItemModel;
+
+/**
+ * @brief import one or more keys into the keyring
+ */
+class KGpgImport: public KGpgTextOrFileTransaction {
+ Q_OBJECT
+
+ Q_DISABLE_COPY(KGpgImport)
+public:
+ /**
+ * @brief import given text
+ * @param parent parent object
+ * @param text key text to import
+ */
+ explicit KGpgImport(QObject *parent, const QString &text = QString());
+
+ /**
+ * @brief import key(s) from file(s)
+ * @param parent parent object
+ * @param files list of file locations to import from
+ */
+ KGpgImport(QObject *parent, const QList<QUrl> &files);
+
+ /**
+ * @brief destructor
+ */
+ virtual ~KGpgImport();
+
+ /**
+ * @brief get the names and short fingerprints of the imported keys
+ * @return list of keys that were imported
+ */
+ QStringList getImportedKeys() const;
+
+ /**
+ * @brief get the full fingerprints of the imported keys
+ * @param log transaction log to scan
+ * @param reason key import reason
+ * @return list of ids that were imported
+ *
+ * You can filter the list of keys returned by the status of that key
+ * as reported by GnuPG. See doc/DETAILS of GnuPG for the meaning of
+ * the different flags.
+ *
+ * If reason is -1 (the default) all processed key ids are returned.
+ * If reason is 0 only keys of status 0 (unchanged) are returned. For
+ * any other value a key is returned if one of his status bits matched
+ * one of the bits in reason (i.e. (reason & status) != 0).
+ */
+ static QStringList getImportedIds(const QStringList &log, const int reason = -1);
+ /**
+ * @brief get the full fingerprints of the imported keys
+ *
+ * This is an overloaded member. It calls the static function with the
+ * result log from this transaction object.
+ */
+ QStringList getImportedIds(const int reason = -1) const;
+
+ /**
+ * @brief get textual summary of the import events
+ * @return messages describing what was imported
+ *
+ * This is an overloaded member. It calls the static function with the
+ * result log from this transaction object.
+ */
+ QString getImportMessage() const;
+
+ /**
+ * @brief get textual summary of the import events
+ * @param log import log
+ * @return messages describing what was imported
+ *
+ * The log must contain a "IMPORT_RES" line. If this is not present
+ * the result string will contain an error message.
+ */
+ static QString getImportMessage(const QStringList &log);
+
+ /**
+ * @brief get detailed summary of import
+ * @param log import log
+ * @return message describing which keys changed and how
+ *
+ * The log must contain a "IMPORT_RES" line. If this is not present
+ * the result string will contain an error message.
+ */
+ static QString getDetailedImportMessage(const QStringList &log, const KGpgItemModel *model = NULL);
+
+ /**
+ * @brief check if the given text contains a private or public key
+ * @param text text to check
+ * @param incomplete assume text is only the beginning of the data
+ * @return if text contains a key or not
+ * @retval 0 no key found
+ * @retval 1 public key found
+ * @retval 2 private key found
+ */
+ static int isKey(const QString &text, const bool incomplete = false);
+
+protected:
+ virtual QStringList command() const;
+};
+
+#endif // KGPGIMPORT_H
diff --git a/mainwindow.cpp b/mainwindow.cpp
index 985ee0d..1b00289 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -756,7 +756,72 @@ void MainWindow::importKeyFromEdit()
return;
}
- keyMgmt->importKeys(edit->curTextPage()->toPlainText().toAscii());
+ //keyMgmt->importKeys(edit->curTextPage()->toPlainText().toAscii());
+ QString text = edit->curTextPage()->toPlainText();
+
+ if (text.isEmpty())
+ return;
+
+ KGpgImport *imp;
+
+ if (!KGpgImport::isKey(text) && KGpgDecrypt::isEncryptedText(text)) {
+ /*if (KMessageBox::questionYesNo(this,
+ i18n("<qt>The text in the clipboard does not look like a key, but like encrypted text.<br />Do you want to decrypt it first and then try importing it?</qt>"),
+ i18n("Import from Clipboard")) != KMessageBox::Yes)
+ return;*/
+
+ imp = new KGpgImport(this);
+ KGpgDecrypt *decr = new KGpgDecrypt(this, text);
+ imp->setInputTransaction(decr);
+ } else {
+ imp = new KGpgImport(this, text);
+ }
+
+ startImport(imp);
+}
+
+void MainWindow::startImport(KGpgImport *import)
+{
+ qDebug() << "start import";
+ //changeMessage(i18n("Importing..."), true);
+ connect(import, SIGNAL(done(int)), SLOT(slotImportDone(int)));
+ import->start();
+}
+
+void MainWindow::slotImportDone(int result)
+{
+ KGpgImport *import = qobject_cast<KGpgImport *>(sender());
+
+ qDebug() << "import Done";
+
+ Q_ASSERT(import != NULL);
+ const QStringList rawmsgs(import->getMessages());
+
+ if (result != 0) {
+ /*KMessageBox::detailedSorry(this, i18n("Key importing failed. Please see the detailed log for more information."),
+ rawmsgs.join( QLatin1String( "\n")) , i18n("Key Import" ));*/
+ qDebug() << "Key importing failed. Please see the detailed log for more information." << rawmsgs.join( QLatin1String( "\n"));
+ }
+
+ QStringList keys(import->getImportedIds(0x1f));
+ const bool needsRefresh = !keys.isEmpty();
+ keys << import->getImportedIds(0);
+/*
+ if (!keys.isEmpty()) {
+ const QString msg(import->getImportMessage());
+ const QStringList keynames(import->getImportedKeys());
+
+ new KgpgDetailedInfo(this, msg, rawmsgs.join( QLatin1String( "\n") ), keynames, i18n("Key Import" ));
+ if (needsRefresh)
+ imodel->refreshKeys(keys);
+ else
+ changeMessage(i18nc("Application ready for user input", "Ready"));
+ } else{
+ changeMessage(i18nc("Application ready for user input", "Ready"));
+ }
+*/
+ mCtx->emitKeyDBChanged();
+ import->deleteLater();
}
void MainWindow::openKeyManagement()
diff --git a/mainwindow.h b/mainwindow.h
index c9867c2..ea047e4 100644
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -34,6 +34,7 @@
#include "kgpg/transactions/kgpgencrypt.h"
#include "kgpg/transactions/kgpgdecrypt.h"
#include "kgpg/transactions/kgpgexport.h"
+#include "kgpg/transactions/kgpgimport.h"
QT_BEGIN_NAMESPACE
class QMainWindow;
@@ -119,6 +120,8 @@ private slots:
* @details Import keys from currently active tab to keylist if possible.
*/
void importKeyFromEdit();
+ void startImport(KGpgImport *import);
+ void slotImportDone(int result);
/**
* @details Append the selected keys to currently active textedit.