aboutsummaryrefslogtreecommitdiffstats
path: root/kgpg/kgpginterface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kgpg/kgpginterface.cpp')
-rw-r--r--kgpg/kgpginterface.cpp439
1 files changed, 439 insertions, 0 deletions
diff --git a/kgpg/kgpginterface.cpp b/kgpg/kgpginterface.cpp
new file mode 100644
index 0000000..8632897
--- /dev/null
+++ b/kgpg/kgpginterface.cpp
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2002 Jean-Baptiste Mardelle <[email protected]>
+ * Copyright (C) 2007,2008,2009,2010,2011,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 "kgpginterface.h"
+
+#include "gpgproc.h"
+#include "core/convert.h"
+#include "core/KGpgKeyNode.h"
+#include "core/KGpgSignNode.h"
+#include "core/KGpgSubkeyNode.h"
+#include "core/KGpgUatNode.h"
+#include "core/KGpgUidNode.h"
+
+/*#include <KConfig>
+#include <KDebug>
+#include <KGlobal>
+#include <KLocale>
+#include <KMessageBox>
+#include <KPasswordDialog>
+#include <KProcess>
+#include <KPushButton>*/
+#include <QFile>
+#include <QPointer>
+#include <QString>
+#include <QTextStream>
+#include <QDebug>
+#include <QInputDialog>
+
+using namespace KgpgCore;
+
+QString KgpgInterface::getGpgSetting(const QString &name, const QString &configfile)
+{
+ const QString tmp(name.simplified() + QLatin1Char( ' ' ));
+ QFile qfile(configfile);
+
+ if (qfile.open(QIODevice::ReadOnly) && (qfile.exists())) {
+ QTextStream t(&qfile);
+ while (!t.atEnd()) {
+ QString result(t.readLine().simplified());
+ if (result.startsWith(tmp)) {
+ result = result.mid(tmp.length()).simplified();
+ return result.section(QLatin1Char( ' ' ), 0, 0);
+ }
+ }
+ qfile.close();
+ }
+
+ return QString();
+}
+
+void KgpgInterface::setGpgSetting(const QString &name, const QString &value, const QString &url)
+{
+ QFile qfile(url);
+
+ if (qfile.open(QIODevice::ReadOnly) && (qfile.exists())) {
+ const QString temp(name + QLatin1Char( ' ' ));
+ QString texttowrite;
+ bool found = false;
+ QTextStream t(&qfile);
+
+ while (!t.atEnd()) {
+ QString result = t.readLine();
+ if (result.simplified().startsWith(temp)) {
+ if (!value.isEmpty())
+ result = temp + QLatin1Char( ' ' ) + value;
+ else
+ result.clear();
+ found = true;
+ }
+
+ texttowrite += result + QLatin1Char( '\n' );
+ }
+
+ qfile.close();
+ if ((!found) && (!value.isEmpty()))
+ texttowrite += QLatin1Char( '\n' ) + temp + QLatin1Char( ' ' ) + value;
+
+ if (qfile.open(QIODevice::WriteOnly)) {
+ QTextStream t(&qfile);
+ t << texttowrite;
+ qfile.close();
+ }
+ }
+}
+
+bool KgpgInterface::getGpgBoolSetting(const QString &name, const QString &configfile)
+{
+ QFile qfile(configfile);
+ if (qfile.open(QIODevice::ReadOnly) && (qfile.exists())) {
+ QTextStream t(&qfile);
+ while (!t.atEnd()) {
+ if (t.readLine().simplified().startsWith(name))
+ return true;
+ }
+ qfile.close();
+ }
+ return false;
+}
+
+void KgpgInterface::setGpgBoolSetting(const QString &name, const bool enable, const QString &url)
+{
+ QFile qfile(url);
+
+ if (qfile.open(QIODevice::ReadOnly) && (qfile.exists())) {
+ QString texttowrite;
+ bool found = false;
+ QTextStream t(&qfile);
+
+ while (!t.atEnd()) {
+ QString result(t.readLine());
+
+ if (result.simplified().startsWith(name)) {
+ if (enable)
+ result = name;
+ else
+ result.clear();
+
+ found = true;
+ }
+
+ texttowrite += result + QLatin1Char( '\n' );
+ }
+ qfile.close();
+
+ if ((!found) && (enable))
+ texttowrite += name;
+
+ if (qfile.open(QIODevice::WriteOnly)) {
+ QTextStream t(&qfile);
+ t << texttowrite;
+ qfile.close();
+ }
+ }
+}
+
+int KgpgInterface::sendPassphrase(const QString &text, KProcess *process, QWidget *widget)
+{
+ qDebug() << "KgpgInterface::sendPassphrase called";
+
+ QPointer<KProcess> gpgprocess = process;
+ QByteArray passphrase;
+ //int code;
+ bool ok;
+
+ /*QPointer<KPasswordDialog> dlg = new KPasswordDialog(widget);
+ QObject::connect(process, SIGNAL(processExited()), dlg->button(KDialog::Cancel), SLOT(click()));
+ dlg->setPrompt(text);
+ code = dlg->exec();
+
+ if (!dlg.isNull())
+ passphrase = dlg->password().toUtf8();
+ delete dlg;
+
+ if (code != KPasswordDialog::Accepted)
+ return 1;
+*/
+
+ QString password = QInputDialog::getText(QApplication::activeWindow(), QObject::tr("Enter Password"),
+ text, QLineEdit::Password,
+ "", &ok);
+
+ if(!ok) return 1;
+
+ passphrase = password.toAscii();
+
+ if (!gpgprocess.isNull()) {
+ gpgprocess->write(passphrase + '\n');
+ }
+
+ return 0;
+}
+
+/**
+ * @param p the process that reads the GnuPG data
+ * @param readNode the node where the signatures are read for
+ */
+static KgpgCore::KgpgKeyList
+readPublicKeysProcess(GPGProc &p, KGpgKeyNode *readNode)
+{
+ QStringList lsp;
+ int items;
+ KgpgCore::KgpgKeyList publiclistkeys;
+ KgpgCore::KgpgKey *publickey = NULL;
+ unsigned int idIndex = 0;
+ QString log;
+ KGpgSignableNode *currentSNode = NULL; ///< the current (sub)node signatures are read for
+
+ while ((items = p.readln(lsp)) >= 0) {
+ if ((lsp.at(0) == QLatin1String( "pub" )) && (items >= 10)) {
+ publiclistkeys << KgpgKey(lsp.at(4), lsp.at(2).toUInt(), Convert::toTrust(lsp.at(1)),
+ Convert::toAlgo(lsp.at(3).toInt()), QDateTime::fromTime_t(lsp.at(5).toUInt()));
+
+ publickey = &publiclistkeys.last();
+
+ publickey->setOwnerTrust(Convert::toOwnerTrust(lsp.at(8)));
+
+ if (lsp.at(6).isEmpty())
+ publickey->setExpiration(QDateTime());
+ else
+ publickey->setExpiration(QDateTime::fromTime_t(lsp.at(6).toUInt()));
+
+ publickey->setValid((items <= 11) || !lsp.at(11).contains(QLatin1Char( 'D' ), Qt::CaseSensitive)); // disabled key
+
+ idIndex = 0;
+ } else if ((lsp.at(0) == QLatin1String( "fpr" )) && (items >= 10)) {
+ const QString fingervalue(lsp.at(9));
+
+ publickey->setFingerprint(fingervalue);
+ } else if ((lsp.at(0) == QLatin1String( "sub" )) && (items >= 7)) {
+ KgpgSubKeyType subtype;
+
+ if (items > 11) {
+ if (lsp.at(11).contains(QLatin1Char( 's' )))
+ subtype |= SKT_SIGNATURE;
+ if (lsp.at(11).contains(QLatin1Char( 'e' )))
+ subtype |= SKT_ENCRYPTION;
+ if (lsp.at(11).contains(QLatin1Char( 'e' )))
+ subtype |= SKT_AUTHENTICATION;
+ if (lsp.at(11).contains(QLatin1Char( 'e' )))
+ subtype |= SKT_CERTIFICATION;
+ }
+
+ KgpgKeySub sub(lsp.at(4), lsp.at(2).toUInt(), Convert::toTrust(lsp.at(1)),
+ Convert::toAlgo(lsp.at(3).toInt()), subtype, QDateTime::fromTime_t(lsp.at(5).toUInt()));
+
+ // FIXME: Please see kgpgkey.h, KgpgSubKey class
+ if (items <= 11)
+ sub.setValid(true);
+ else
+ sub.setValid(!lsp.at(11).contains(QLatin1Char( 'D' )));
+
+ if (lsp.at(6).isEmpty())
+ sub.setExpiration(QDateTime());
+ else
+ sub.setExpiration(QDateTime::fromTime_t(lsp.at(6).toUInt()));
+
+ publickey->subList()->append(sub);
+ if (readNode == NULL)
+ currentSNode = NULL;
+ else
+ currentSNode = new KGpgSubkeyNode(readNode, sub);
+ } else if (lsp.at(0) == QLatin1String( "uat" )) {
+ idIndex++;
+ if (readNode != NULL) {
+ currentSNode = new KGpgUatNode(readNode, idIndex, lsp);
+ }
+ } else if ((lsp.at(0) == QLatin1String( "uid" )) && (items >= 10)) {
+ if (idIndex == 0) {
+ QString fullname(lsp.at(9));
+ QString kmail;
+ if (fullname.contains(QLatin1Char( '<' )) ) {
+ kmail = fullname;
+
+ if (fullname.contains(QLatin1Char( ')' )) )
+ kmail = kmail.section(QLatin1Char( ')' ), 1);
+
+ kmail = kmail.section(QLatin1Char( '<' ), 1);
+ kmail.truncate(kmail.length() - 1);
+
+ if (kmail.contains(QLatin1Char( '<' ))) {
+ // several email addresses in the same key
+ kmail = kmail.replace(QLatin1Char( '>' ), QLatin1Char( ';' ));
+ kmail.remove(QLatin1Char( '<' ));
+ }
+ }
+
+ QString kname(fullname.section( QLatin1String( " <" ), 0, 0));
+ QString comment;
+ if (fullname.contains(QLatin1Char( '(' )) ) {
+ kname = kname.section( QLatin1String( " (" ), 0, 0);
+ comment = fullname.section(QLatin1Char( '(' ), 1, 1);
+ comment = comment.section(QLatin1Char( ')' ), 0, 0);
+ }
+
+ idIndex++;
+ publickey->setEmail(kmail);
+ publickey->setComment(comment);
+ publickey->setName(kname);
+
+ currentSNode = readNode;
+ } else {
+ idIndex++;
+ if (readNode != NULL) {
+ currentSNode = new KGpgUidNode(readNode, idIndex, lsp);
+ }
+ }
+ } else if (((lsp.at(0) == QLatin1String( "sig" )) || (lsp.at(0) == QLatin1String( "rev" ))) && (items >= 11)) {
+ // there are no strings here that could have a recoded QLatin1Char( ':' ) in them
+ const QString signature = lsp.join(QLatin1String(":"));
+
+ if (currentSNode != NULL)
+ (void) new KGpgSignNode(currentSNode, lsp);
+ } else {
+ log += lsp.join(QString(QLatin1Char( ':' ))) + QLatin1Char( '\n' );
+ }
+ }
+
+ if (p.exitCode() != 0) {
+// KMessageBox::detailedError(NULL, i18n("An error occurred while scanning your keyring"), log);
+ qDebug() << "An error occurred while scanning your keyring" << " - " << log;
+ log.clear();
+ }
+
+ return publiclistkeys;
+}
+
+KgpgKeyList KgpgInterface::readPublicKeys(const QStringList &ids)
+{
+ GPGProc process;
+ process <<
+ QLatin1String("--with-colons") <<
+ QLatin1String("--with-fingerprint") <<
+ QLatin1String("--fixed-list-mode") <<
+ QLatin1String("--homedir") << GPGProc::getGpgHome("") <<
+ QLatin1String("--list-keys") <<
+ ids;
+
+ process.setOutputChannelMode(KProcess::MergedChannels);
+
+ process.start();
+ process.waitForFinished(-1);
+ return readPublicKeysProcess(process, NULL);
+}
+
+void KgpgInterface::readSignatures(KGpgKeyNode *node)
+{
+ GPGProc process;
+ process <<
+ QLatin1String("--with-colons") <<
+ QLatin1String("--with-fingerprint") <<
+ QLatin1String("--fixed-list-mode") <<
+ QLatin1String("--list-sigs") <<
+ node->getId();
+
+ process.setOutputChannelMode(KProcess::MergedChannels);
+
+ process.start();
+ process.waitForFinished(-1);
+
+ readPublicKeysProcess(process, node);
+}
+
+static KgpgCore::KgpgKeyList
+readSecretKeysProcess(GPGProc &p)
+{
+ QStringList lsp;
+ int items;
+ bool hasuid = true;
+ KgpgCore::KgpgKeyList result;
+ KgpgCore::KgpgKey *secretkey = NULL;
+
+ while ( (items = p.readln(lsp)) >= 0 ) {
+ if ((lsp.at(0) == QLatin1String( "sec" )) && (items >= 10)) {
+ result << KgpgKey(lsp.at(4), lsp.at(2).toUInt(), Convert::toTrust(lsp.at(1)),
+ Convert::toAlgo(lsp.at(3).toInt()), QDateTime::fromTime_t(lsp.at(5).toUInt()));
+
+ secretkey = &result.last();
+
+ secretkey->setSecret(true);
+
+ if (lsp.at(6).isEmpty())
+ secretkey->setExpiration(QDateTime());
+ else
+ secretkey->setExpiration(QDateTime::fromTime_t(lsp.at(6).toUInt()));
+ hasuid = true;
+ } else if ((lsp.at(0) == QLatin1String( "uid" )) && (items >= 10)) {
+ if (hasuid)
+ continue;
+
+ hasuid = true;
+
+ const QString fullname(lsp.at(9));
+ if (fullname.contains(QLatin1Char( '<' ) )) {
+ QString kmail(fullname);
+
+ if (fullname.contains(QLatin1Char( ')' ) ))
+ kmail = kmail.section(QLatin1Char( ')' ), 1);
+
+ kmail = kmail.section(QLatin1Char( '<' ), 1);
+ kmail.truncate(kmail.length() - 1);
+
+ if (kmail.contains(QLatin1Char( '<' ) )) { // several email addresses in the same key
+ kmail = kmail.replace(QLatin1Char( '>' ), QLatin1Char( ';' ));
+ kmail.remove(QLatin1Char( '<' ));
+ }
+
+ secretkey->setEmail(kmail);
+ } else {
+ secretkey->setEmail(QString());
+ }
+
+ QString kname(fullname.section( QLatin1String( " <" ), 0, 0));
+ if (fullname.contains(QLatin1Char( '(' ) )) {
+ kname = kname.section( QLatin1String( " (" ), 0, 0);
+ QString comment = fullname.section(QLatin1Char( '(' ), 1, 1);
+ comment = comment.section(QLatin1Char( ')' ), 0, 0);
+
+ secretkey->setComment(comment);
+ } else {
+ secretkey->setComment(QString());
+ }
+ secretkey->setName(kname);
+ } else if ((lsp.at(0) == QLatin1String( "fpr" )) && (items >= 10)) {
+ secretkey->setFingerprint(lsp.at(9));
+ }
+ }
+
+ return result;
+}
+
+KgpgKeyList KgpgInterface::readSecretKeys(const QStringList &ids)
+{
+ GPGProc process;
+ process <<
+ QLatin1String("--with-colons") <<
+ QLatin1String("--list-secret-keys") <<
+ QLatin1String("--with-fingerprint") <<
+ QLatin1String("--fixed-list-mode") <<
+ ids;
+
+ process.start();
+ process.waitForFinished(-1);
+ KgpgCore::KgpgKeyList result = readSecretKeysProcess(process);
+
+ return result;
+}
+
+//#include "kgpginterface.moc"