diff options
author | ubbo <ubbo@34ebc366-c3a9-4b3c-9f84-69acf7962910> | 2012-08-03 22:46:46 +0000 |
---|---|---|
committer | ubbo <ubbo@34ebc366-c3a9-4b3c-9f84-69acf7962910> | 2012-08-03 22:46:46 +0000 |
commit | 57eb187661072f51c1facf0970a2d70445fd242c (patch) | |
tree | 71ba2b42ef2e176332ee4aefaa3d645b29123d52 | |
parent | append selected keys works (diff) | |
download | gpg4usb-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.pro | 6 | ||||
-rw-r--r-- | gpgcontext.cpp | 4 | ||||
-rw-r--r-- | gpgcontext.h | 2 | ||||
-rw-r--r-- | kgpg/transactions/kgpgimport.cpp | 295 | ||||
-rw-r--r-- | kgpg/transactions/kgpgimport.h | 129 | ||||
-rw-r--r-- | mainwindow.cpp | 67 | ||||
-rw-r--r-- | mainwindow.h | 3 |
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 <%3>", 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. |