diff options
-rw-r--r-- | gpgcontext.cpp | 118 | ||||
-rw-r--r-- | gpgcontext.h | 5 | ||||
-rw-r--r-- | verifydetailsdialog.cpp | 11 | ||||
-rw-r--r-- | verifydetailsdialog.h | 1 | ||||
-rw-r--r-- | verifykeydetailbox.cpp | 1 |
5 files changed, 132 insertions, 4 deletions
diff --git a/gpgcontext.cpp b/gpgcontext.cpp index 3a38333..abc9d03 100644 --- a/gpgcontext.cpp +++ b/gpgcontext.cpp @@ -296,6 +296,124 @@ void GpgContext::emitKeyDBChanged() { emit keyDBChanged(); } +// TODO: from kgpgverify, merge back +static QString +sigTimeMessage(const QString &sigtime) +{ + QDateTime stamp; + if (sigtime.contains(QLatin1Char('T'))) { + stamp = QDateTime::fromString(sigtime, Qt::ISODate); + } else { + bool ok; + qint64 secs = sigtime.toLongLong(&ok); + if (ok) + stamp = QDateTime::fromMSecsSinceEpoch(secs * 1000); + } + + if (!stamp.isValid()) + return QString(); + +/* return tr("first argument is formatted date, second argument is formatted time", + "The signature was created at %1 %2", + KGlobal::locale()->formatDate(stamp.date(), KLocale::LongDate), + KGlobal::locale()->formatTime(stamp.time(), KLocale::LongDate)) + + QLatin1String("<br/>");*/ + return "todo"; +} + +QString GpgContext::getReport(const QStringList &log) +{ + QString result; + // newer versions of GnuPG emit both VALIDSIG and GOODSIG + // for a good signature. Since VALIDSIG has more information + // we use that. + const QRegExp validsig(QLatin1String("^\\[GNUPG:\\] VALIDSIG([ ]+[^ ]+){10,}.*$")); + //const bool useGoodSig = (model != NULL) && (log.indexOf(validsig) == -1); + const bool useGoodSig = log.indexOf(validsig) == -1; + QString sigtime; // timestamp of signature creation + + foreach (const QString &line, log) { + if (!line.startsWith(QLatin1String("[GNUPG:] "))) + continue; + + const QString msg = line.mid(9); + + if (msg.startsWith(QLatin1String("VALIDSIG ")) && !useGoodSig) { + // from GnuPG source, doc/DETAILS: + // VALIDSIG <fingerprint in hex> <sig_creation_date> <sig-timestamp> + // <expire-timestamp> <sig-version> <reserved> <pubkey-algo> + // <hash-algo> <sig-class> <primary-key-fpr> + const QStringList vsig = msg.mid(9).split(QLatin1Char(' '), QString::SkipEmptyParts); + Q_ASSERT(vsig.count() >= 10); + +/* const KGpgKeyNode *node = model->findKeyNode(vsig[9]); + + if (node != NULL) { + // ignore for now if this is signed with the primary id (vsig[0] == vsig[9]) or not + if (node->getEmail().isEmpty()) + result += tr("<qt>Good signature from:<br /><b>%1</b><br />Key ID: %2<br /></qt>") + .arg(node->getName()).arg(vsig[9]); + else + result += tr("Good signature from: NAME <EMAIL>, Key ID: HEXID", + "<qt>Good signature from:<br /><b>%1 <%2></b><br />Key ID: %3<br /></qt>") + .arg(node->getName()).arg(node->getEmail()).arg(vsig[9]); + + result += sigTimeMessage(vsig[2]); + } else { + // this should normally never happen, but one could delete + // the key just after the verification. Brute force solution: + // do the whole report generation again, but this time make + // sure GOODSIG is used. + return getReport(log, NULL); + }*/ + } else if (msg.startsWith(QLatin1String("UNEXPECTED")) || + msg.startsWith(QLatin1String("NODATA"))) { + result += tr("No signature found.") + QLatin1Char('\n'); + } else if (useGoodSig && msg.startsWith(QLatin1String("GOODSIG "))) { + int sigpos = msg.indexOf( ' ' , 8); + const QString keyid = msg.mid(8, sigpos - 8); + + // split the name/email pair to give translators more power to handle this + QString email; + QString name = msg.mid(sigpos + 1); + + int oPos = name.indexOf(QLatin1Char('<')); + int cPos = name.indexOf(QLatin1Char('>')); + if ((oPos >= 0) && (cPos >= 0)) { + email = name.mid(oPos + 1, cPos - oPos - 1); + name = name.left(oPos).simplified(); + } + + if (email.isEmpty()) + result += tr("<qt>Good signature from:<br /><b>%1</b><br />Key ID: %2<br /></qt>") + .arg(name).arg(keyid); + else + result += tr("Good signature from: NAME <EMAIL>, Key ID: HEXID", + "<qt>Good signature from:<br /><b>%1 <%2></b><br />Key ID: %3<br /></qt>") + .arg(name).arg(email).arg(keyid); + if (!sigtime.isEmpty()) { + result += sigTimeMessage(sigtime); + sigtime.clear(); + } + } else if (msg.startsWith(QLatin1String("SIG_ID "))) { + const QStringList parts = msg.simplified().split(QLatin1Char(' ')); + if (parts.count() > 2) + sigtime = parts[2]; + } else if (msg.startsWith(QLatin1String("BADSIG"))) { + int sigpos = msg.indexOf( ' ', 7); + result += tr("<qt><b>BAD signature</b> from:<br /> %1<br />Key id: %2<br /><br /><b>The file is corrupted</b><br /></qt>") + .arg(msg.mid(sigpos + 1).replace(QLatin1Char('<'), QLatin1String("<"))) + .arg(msg.mid(7, sigpos - 7)); + } else if (msg.startsWith(QLatin1String("TRUST_UNDEFINED"))) { + result += tr("<qt>The signature is valid, but the key is untrusted<br /></qt>"); + } else if (msg.startsWith(QLatin1String("TRUST_ULTIMATE"))) { + result += tr("<qt>The signature is valid, and the key is ultimately trusted<br /></qt>"); + } + } + + return result; +} + } diff --git a/gpgcontext.h b/gpgcontext.h index 304faa5..d04034b 100644 --- a/gpgcontext.h +++ b/gpgcontext.h @@ -28,6 +28,7 @@ #include <QLinkedList> #include <QtGui> #include "kgpg/core/kgpgkey.h" +#include "kgpg/transactions/kgpgverify.h" QT_BEGIN_NAMESPACE class QMessageBox; @@ -134,7 +135,9 @@ public: * \li 0, if the text is not signed at all. */ int textIsSigned(const QByteArray &text); - QString beautifyFingerprint(QString fingerprint); + static QString beautifyFingerprint(QString fingerprint); + + static QString getReport(const QStringList &log); signals: void keyDBChanged(); diff --git a/verifydetailsdialog.cpp b/verifydetailsdialog.cpp index 55cd11c..a45521d 100644 --- a/verifydetailsdialog.cpp +++ b/verifydetailsdialog.cpp @@ -47,7 +47,7 @@ void VerifyDetailsDialog::slotRefresh() mVbox->close(); mVbox = new QWidget(); - QVBoxLayout *mVboxLayout = new QVBoxLayout(mVbox); + mVboxLayout = new QVBoxLayout(mVbox); mainLayout->addWidget(mVbox); // Button Box for close button @@ -114,8 +114,13 @@ void VerifyDetailsDialog::slotVerifyDone(int result) { sender()->deleteLater(); Q_ASSERT(verify != NULL); - const QStringList messages = verify->getMessages(); + /*const QStringList messages = verify->getMessages(); foreach(QString mess, messages) { qDebug() << "vm: " << mess; - } + }*/ + + QString report = GpgME::GpgContext::getReport(verify->getMessages()); + mVboxLayout->addWidget(new QLabel(report)); + + } diff --git a/verifydetailsdialog.h b/verifydetailsdialog.h index 814def2..bd4379b 100644 --- a/verifydetailsdialog.h +++ b/verifydetailsdialog.h @@ -44,6 +44,7 @@ private: QString mInputData; /** Data to be verified */ QByteArray* mInputSignature; /** Data to be verified */ QDialogButtonBox* buttonBox; + QVBoxLayout *mVboxLayout; }; #endif // __VERIFYDETAILSDIALOG_H__ diff --git a/verifykeydetailbox.cpp b/verifykeydetailbox.cpp index a51f1d2..521d122 100644 --- a/verifykeydetailbox.cpp +++ b/verifykeydetailbox.cpp @@ -27,6 +27,7 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(QWidget *parent, GpgME::GpgContext* ctx, this->mCtx = ctx; this->mKeyList = keyList; //this->fpr=signature->fpr; + qDebug() << "dbsig report: " << GpgME::GpgContext::getReport(signature.getMessages()); QGridLayout *grid = new QGridLayout(); // TODO |