diff options
| author | Andre Heinecke <[email protected]> | 2016-08-11 15:22:35 +0000 | 
|---|---|---|
| committer | Andre Heinecke <[email protected]> | 2016-08-11 16:00:14 +0000 | 
| commit | 8c5abc8d932affab4bc79a85e3f98f6f6b982ae8 (patch) | |
| tree | 447e9bb4bed56935501ac96f08f0f86cd2033e69 /lang | |
| parent | doc: Get rid of version.texi (diff) | |
| download | gpgme-8c5abc8d932affab4bc79a85e3f98f6f6b982ae8.tar.gz gpgme-8c5abc8d932affab4bc79a85e3f98f6f6b982ae8.zip | |
Qt: Add KeyForMailboxJob
* lang/qt/src/job.cpp: Include moc and make subclass.
* lang/qt/src/keyformailboxjob.h,
lang/qt/src/qgpgmekeyformailboxjob.cpp,
lang/qt/src/qgpgmekeyformailboxjob.h: New.
* lang/qt/tests/run-keyformailboxjob.cpp: New manual test.
* lang/qt/tests/Makefile.am: Add run-keyformailboxjob.
* lang/qt/src/Makefile.am: Update accordingly.
* lang/qt/src/protocol.h, lang/qt/src/protocol_p.h: Add
keyformailboxjob.
--
The KeyForMailboxjob can be used to determine the best key to
use to encrypt something to a given mail address.
Diffstat (limited to 'lang')
| -rw-r--r-- | lang/qt/src/Makefile.am | 11 | ||||
| -rw-r--r-- | lang/qt/src/job.cpp | 3 | ||||
| -rw-r--r-- | lang/qt/src/keyformailboxjob.h | 101 | ||||
| -rw-r--r-- | lang/qt/src/protocol.h | 3 | ||||
| -rw-r--r-- | lang/qt/src/protocol_p.h | 10 | ||||
| -rw-r--r-- | lang/qt/src/qgpgmekeyformailboxjob.cpp | 136 | ||||
| -rw-r--r-- | lang/qt/src/qgpgmekeyformailboxjob.h | 79 | ||||
| -rw-r--r-- | lang/qt/tests/Makefile.am | 4 | ||||
| -rw-r--r-- | lang/qt/tests/run-keyformailboxjob.cpp | 56 | 
9 files changed, 399 insertions, 4 deletions
| diff --git a/lang/qt/src/Makefile.am b/lang/qt/src/Makefile.am index ae316bac..59d8abc8 100644 --- a/lang/qt/src/Makefile.am +++ b/lang/qt/src/Makefile.am @@ -33,7 +33,7 @@ qgpgme_sources = \      qgpgmesecretkeyexportjob.cpp qgpgmesignencryptjob.cpp \      qgpgmesignjob.cpp qgpgmesignkeyjob.cpp qgpgmeverifydetachedjob.cpp \      qgpgmeverifyopaquejob.cpp threadedjobmixin.cpp \ -    gpgme_backend_debug.cpp +    qgpgmekeyformailboxjob.cpp gpgme_backend_debug.cpp  # If you add one here make sure that you also add one in camelcase  qgpgme_headers= \ @@ -49,6 +49,7 @@ qgpgme_headers= \      exportjob.h \      hierarchicalkeylistjob.h \      job.h \ +    keyformailboxjob.h \      multideletejob.h \      protocol.h \      qgpgme_export.h \ @@ -95,7 +96,8 @@ camelcase_headers= \      KeyGenerationJob \      KeyListJob \      ListAllKeysJob \ -    VerifyDetachedJob +    VerifyDetachedJob \ +    KeyForMailboxJob  private_qgpgme_headers = \      qgpgme_export.h \ @@ -124,6 +126,7 @@ private_qgpgme_headers = \      qgpgmesignkeyjob.h \      qgpgmeverifydetachedjob.h \      qgpgmeverifyopaquejob.h \ +    qgpgmekeyformailboxjob.h \      specialjob.h \      threadedjobmixin.h @@ -175,7 +178,9 @@ qgpgme_moc_sources = \      signkeyjob.moc \      specialjob.moc \      verifydetachedjob.moc \ -    verifyopaquejob.moc +    verifyopaquejob.moc \ +    keyformailboxjob.moc \ +    qgpgmekeyformailboxjob.moc  qgpgmeincludedir = $(includedir)/qgpgme  qgpgmeinclude_HEADERS = $(qgpgme_headers) diff --git a/lang/qt/src/job.cpp b/lang/qt/src/job.cpp index 7ca1df9b..8e506474 100644 --- a/lang/qt/src/job.cpp +++ b/lang/qt/src/job.cpp @@ -55,6 +55,7 @@  #include "refreshkeysjob.h"  #include "adduseridjob.h"  #include "specialjob.h" +#include "keyformailboxjob.h"  #include <QCoreApplication>  #include <QDebug> @@ -120,6 +121,7 @@ make_job_subclass(DeleteJob)  make_job_subclass(RefreshKeysJob)  make_job_subclass(AddUserIDJob)  make_job_subclass(SpecialJob) +make_job_subclass(KeyForMailboxJob)  #undef make_job_subclass @@ -148,3 +150,4 @@ make_job_subclass(SpecialJob)  #include "refreshkeysjob.moc"  #include "adduseridjob.moc"  #include "specialjob.moc" +#include "keyformailboxjob.moc" diff --git a/lang/qt/src/keyformailboxjob.h b/lang/qt/src/keyformailboxjob.h new file mode 100644 index 00000000..9e76df51 --- /dev/null +++ b/lang/qt/src/keyformailboxjob.h @@ -0,0 +1,101 @@ +/* +    keyformailboxjob.h + +    This file is part of qgpgme, the Qt API binding for gpgme +    Copyright (c) 2016 Intevation GmbH + +    QGpgME 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. + +    QGpgME 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 this program; if not, write to the Free Software +    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + +    In addition, as a special exception, the copyright holders give +    permission to link the code of this program with any edition of +    the Qt library by Trolltech AS, Norway (or with modified versions +    of Qt that use the same license as Qt), and distribute linked +    combinations including the two.  You must obey the GNU General +    Public License in all respects for all of the code used other than +    Qt.  If you modify this file, you may extend this exception to +    your version of the file, but you are not obligated to do so.  If +    you do not wish to do so, delete this exception statement from +    your version. +*/ +#ifndef __KLEO_KEYFORMAILBOX_H__ +#define __KLEO_KEYFORMAILBOX_H__ + +#include <QString> + +#include "job.h" + +#include <gpgme++/key.h> +namespace GpgME +{ +class Error; +class KeyListResult; +} + +namespace QGpgME +{ + +/** +   @short Get the best key to use for a Mailbox + +   To use the keyformailboxjob, first obtain an instance from the +   CryptoBackend and either exec it or start and +   conncet the result() signals to a suitable slot. +   The job will be automatically deleted in which +   case the KeylistJob instance will have schedules it's own +   destruction with a call to QObject::deleteLater(). + +   The best key is defined as the key with a UID that has an +   E-Mail that matches the mailbox provided. If multiple +   keys are found the one with the highest validity is returned. + +   After result() is emitted, the +   KeyListJob will schedule it's own destruction by calling +   QObject::deleteLater(). +*/ +class QGPGME_EXPORT KeyForMailboxJob: public Job +{ +    Q_OBJECT +protected: +    explicit KeyForMailboxJob(QObject *parent); + +public: +    ~KeyForMailboxJob(); + +    /** +      Starts the operation. \a mailbox is the mailbox to +      look for. + +      The result is the same as for the LocateKeysJob. + +      If \a canEncrypt is true, only keys that have a subkey for encryption +      usage are returned. Use this if you need to select a +      key for signing. +    */ +    virtual GpgME::Error start(const QString &mailbox, bool canEncrypt = true) = 0; + +    virtual GpgME::KeyListResult exec(const QString &mailbox, bool canEncrypt, GpgME::Key &key, GpgME::UserID &uid) = 0; + +Q_SIGNALS: +    /** The result. \a Key is the key found or a Null key. +     * +     * The userid is the uid where the mailbox matches. +     * +     * The auditlog params are always null / empty. +     */ +    void result(const GpgME::KeyListResult &result, const GpgME::Key &key, const GpgME::UserID &uid, const QString &auditLogAsHtml = QString(), const GpgME::Error &auditLogError = GpgME::Error()); +}; + +} +#endif diff --git a/lang/qt/src/protocol.h b/lang/qt/src/protocol.h index 64146b82..23b9d937 100644 --- a/lang/qt/src/protocol.h +++ b/lang/qt/src/protocol.h @@ -62,6 +62,7 @@ class ChangeOwnerTrustJob;  class ChangePasswdJob;  class AddUserIDJob;  class SpecialJob; +class KeyForMailboxJob;  /** The main entry point for QGpgME Comes in OpenPGP and SMIME(CMS) flavors.   * @@ -145,6 +146,8 @@ public:       * with both includeSigs and validate options.       */      virtual KeyListJob *locateKeysJob() const = 0; +    /** Find the best key to use for a mailbox. */ +    virtual KeyForMailboxJob *keyForMailboxJob() const = 0;  };  /** Obtain a reference to the OpenPGP Protocol. diff --git a/lang/qt/src/protocol_p.h b/lang/qt/src/protocol_p.h index 9fcbc8b7..afb4f9cb 100644 --- a/lang/qt/src/protocol_p.h +++ b/lang/qt/src/protocol_p.h @@ -56,6 +56,7 @@  #include "qgpgmechangeownertrustjob.h"  #include "qgpgmechangepasswdjob.h"  #include "qgpgmeadduseridjob.h" +#include "qgpgmekeyformailboxjob.h"  namespace  { @@ -377,6 +378,15 @@ public:          context->setKeyListMode(GpgME::Extern | GpgME::Local | GpgME::Signatures | GpgME::Validate);          return new QGpgME::QGpgMEKeyListJob(context);      } + +    QGpgME::KeyForMailboxJob *keyForMailboxJob() const Q_DECL_OVERRIDE +    { +        GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol); +        if (!context) { +            return Q_NULLPTR; +        } +        return new QGpgME::QGpgMEKeyForMailboxJob(context); +    }  };  } diff --git a/lang/qt/src/qgpgmekeyformailboxjob.cpp b/lang/qt/src/qgpgmekeyformailboxjob.cpp new file mode 100644 index 00000000..0702a365 --- /dev/null +++ b/lang/qt/src/qgpgmekeyformailboxjob.cpp @@ -0,0 +1,136 @@ +/* +    qgpgmekeyformailboxjob.cpp + +    This file is part of qgpgme, the Qt API binding for gpgme +    Copyright (c) 2016 Intevation GmbH + +    QGpgME 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. + +    QGpgME 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 this program; if not, write to the Free Software +    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + +    In addition, as a special exception, the copyright holders give +    permission to link the code of this program with any edition of +    the Qt library by Trolltech AS, Norway (or with modified versions +    of Qt that use the same license as Qt), and distribute linked +    combinations including the two.  You must obey the GNU General +    Public License in all respects for all of the code used other than +    Qt.  If you modify this file, you may extend this exception to +    your version of the file, but you are not obligated to do so.  If +    you do not wish to do so, delete this exception statement from +    your version. +*/ + +#include "qgpgmekeyformailboxjob.h" +#include "qgpgmekeylistjob.h" + +#include <tuple> + +using namespace GpgME; +using namespace QGpgME; + +QGpgMEKeyForMailboxJob::QGpgMEKeyForMailboxJob(Context *context) +    : mixin_type(context) +{ +    lateInitialization(); +} + +QGpgMEKeyForMailboxJob::~QGpgMEKeyForMailboxJob() {} + +static bool keyIsOk(const Key k) +{ +    return !k.isExpired() && !k.isRevoked() && !k.isInvalid() && !k.isDisabled(); +} + +static bool uidIsOk(const UserID uid) +{ +    return keyIsOk(uid.parent()) && !uid.isRevoked() && !uid.isInvalid(); +} + +static bool subkeyIsOk(const Subkey s) +{ +    return !s.isRevoked() && !s.isInvalid() && !s.isDisabled(); +} + +static QGpgMEKeyForMailboxJob::result_type do_work(Context *ctx, const QString &mailbox, bool canEncrypt) +{ +    /* Do a Keylisting. */ +    ctx->setKeyListMode(GpgME::Extern | GpgME::Local | GpgME::Signatures | GpgME::Validate); +    std::vector<Key> keys; +    QGpgMEKeyListJob *keylist = new QGpgMEKeyListJob(ctx); + +    KeyListResult result = keylist->exec(QStringList() << mailbox, false, keys); + +    if (result.error()) { +        return std::make_tuple(result, Key(), UserID(), QString(), Error()); +    } + +    // This should ideally be decided by GnuPG and this Job changed +    // to just call the according API in GpgME +    // See: https://bugs.gnupg.org/gnupg/issue2359 +    Key keyC; +    UserID uidC; +    Q_FOREACH (const Key k, keys) { +        if (canEncrypt && !k.canEncrypt()) { +            continue; +        } +        /* First get the uid that matches the mailbox */ +        Q_FOREACH (const UserID u, k.userIDs()) { +            if (QString::fromUtf8(u.email()).toLower() == mailbox.toLower()) { +                if (uidC.isNull()) { +                    keyC = k; +                    uidC = u; +                } else if ((!uidIsOk(uidC) && uidIsOk(u)) || uidC.validity() < u.validity()) { +                    /* Validity of the new key is better. */ +                    uidC = u; +                    keyC = k; +                } else if (uidC.validity() == u.validity() && uidIsOk(u)) { +                    /* Both are the same check which one is newer. */ +                    time_t oldTime = 0; +                    Q_FOREACH (const Subkey s, keyC.subkeys()) { +                        if ((canEncrypt && s.canEncrypt()) && subkeyIsOk(s)) { +                            oldTime = s.creationTime(); +                        } +                    } +                    time_t newTime = 0; +                    Q_FOREACH (const Subkey s, k.subkeys()) { +                        if ((canEncrypt && s.canEncrypt()) && subkeyIsOk(s)) { +                            newTime = s.creationTime(); +                        } +                    } +                    if (newTime > oldTime) { +                        uidC = u; +                        keyC = k; +                    } +                } +            } +        } +    } +    return std::make_tuple(result, keyC, uidC, QString(), Error()); +} + +Error QGpgMEKeyForMailboxJob::start(const QString &mailbox, bool canEncrypt) +{ +    run(std::bind(&do_work, std::placeholders::_1, mailbox, canEncrypt)); +    return Error(); +} + +KeyListResult QGpgMEKeyForMailboxJob::exec(const QString &mailbox, bool canEncrypt, Key &key, UserID &uid) +{ +    const result_type r = do_work(context(), mailbox, canEncrypt); +    resultHook(r); +    key = std::get<1>(r); +    uid = std::get<2>(r); +    return std::get<0>(r); +} + +#include "qgpgmekeyformailboxjob.moc" diff --git a/lang/qt/src/qgpgmekeyformailboxjob.h b/lang/qt/src/qgpgmekeyformailboxjob.h new file mode 100644 index 00000000..02a16d32 --- /dev/null +++ b/lang/qt/src/qgpgmekeyformailboxjob.h @@ -0,0 +1,79 @@ +/* +    qgpgmekeyformailboxjob.h + +    This file is part of libkleopatra, the KDE keymanagement library +    Copyright (c) 2004,2008 Klarälvdalens Datakonsult AB +    This file is part of qgpgme, the Qt API binding for gpgme +    Copyright (c) 2016 Intevation GmbH + +    QGpgME 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. + +    QGpgME 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 this program; if not, write to the Free Software +    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + +    In addition, as a special exception, the copyright holders give +    permission to link the code of this program with any edition of +    the Qt library by Trolltech AS, Norway (or with modified versions +    of Qt that use the same license as Qt), and distribute linked +    combinations including the two.  You must obey the GNU General +    Public License in all respects for all of the code used other than +    Qt.  If you modify this file, you may extend this exception to +    your version of the file, but you are not obligated to do so.  If +    you do not wish to do so, delete this exception statement from +    your version. +*/ + +#ifndef __QGPGME_QGPGMEKEYFORMAILBOXJOB_H__ +#define __QGPGME_QGPGMEKEYFORMAILBOXJOB_H__ +#include "keyformailboxjob.h" + +#include "threadedjobmixin.h" + +#include <gpgme++/keylistresult.h> +#include <gpgme++/key.h> + +namespace QGpgME +{ + +class QGpgMEKeyForMailboxJob +#ifdef Q_MOC_RUN +    : public KeyForMailboxJob +#else +    : public _detail::ThreadedJobMixin<KeyForMailboxJob, std::tuple<GpgME::KeyListResult, GpgME::Key, GpgME::UserID, QString, GpgME::Error> > +#endif +{ +    Q_OBJECT +#ifdef Q_MOC_RUN +public Q_SLOTS: +    void slotFinished(); +#endif +public: +    explicit QGpgMEKeyForMailboxJob(GpgME::Context *context); +    ~QGpgMEKeyForMailboxJob(); + +    /** +      Starts the operation. \a mailbox is the mailbox to +      look for. + +      The result is the same as for the LocateKeysJob. + +      If \a canEncrypt is true, only keys that have a subkey for encryption +      usage are returned. Use this if you need to select a +      key for signing. +    */ +    GpgME::Error start(const QString &mailbox, bool canEncrypt = true) Q_DECL_OVERRIDE; + +    GpgME::KeyListResult exec(const QString &mailbox, bool canEncrypt, GpgME::Key &key, GpgME::UserID &uid) Q_DECL_OVERRIDE; +}; + +} +#endif diff --git a/lang/qt/tests/Makefile.am b/lang/qt/tests/Makefile.am index 13495a81..85f6fa6b 100644 --- a/lang/qt/tests/Makefile.am +++ b/lang/qt/tests/Makefile.am @@ -55,12 +55,14 @@ t_keylocate_SOURCES = t-keylocate.cpp $(support_src)  t_ownertrust_SOURCES = t-ownertrust.cpp $(support_src)  t_tofuinfo_SOURCES = t-tofuinfo.cpp $(support_src)  t_encrypt_SOURCES = t-encrypt.cpp $(support_src) +run_keyformailboxjob_SOURCES = run-keyformailboxjob.cpp  nodist_t_keylist_SOURCES = $(moc_files)  BUILT_SOURCES = $(moc_files) -noinst_PROGRAMS = t-keylist t-keylocate t-ownertrust t-tofuinfo t-encrypt +noinst_PROGRAMS = t-keylist t-keylocate t-ownertrust t-tofuinfo t-encrypt \ +    run-keyformailboxjob  CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf \  	gpg-agent.conf pubring.kbx~ S.gpg-agent gpg.conf pubring.gpg~ \ diff --git a/lang/qt/tests/run-keyformailboxjob.cpp b/lang/qt/tests/run-keyformailboxjob.cpp new file mode 100644 index 00000000..9ac76682 --- /dev/null +++ b/lang/qt/tests/run-keyformailboxjob.cpp @@ -0,0 +1,56 @@ +/* +    run-keyformailbox.cpp + +    This file is part of QGpgME's test suite. +    Copyright (c) 2016 Intevation GmbH + +    QGpgME is free software; you can redistribute it and/or +    modify it under the terms of the GNU General Public License, +    version 2, as published by the Free Software Foundation. + +    QGpgME 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 this program; if not, write to the Free Software +    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + +    In addition, as a special exception, the copyright holders give +    permission to link the code of this program with any edition of +    the Qt library by Trolltech AS, Norway (or with modified versions +    of Qt that use the same license as Qt), and distribute linked +    combinations including the two.  You must obey the GNU General +    Public License in all respects for all of the code used other than +    Qt.  If you modify this file, you may extend this exception to +    your version of the file, but you are not obligated to do so.  If +    you do not wish to do so, delete this exception statement from +    your version. +*/ + +#include "keyformailboxjob.h" +#include "keylistjob.h" +#include "protocol.h" + +#include "key.h" +#include "keylistresult.h" + +#include <QDebug> + + +int main(int argc, char **argv) +{ +    QString mailbox; +    if (argc == 2) { +        mailbox = QString::fromLocal8Bit(argv[1]); +    } + +    auto job = QGpgME::openpgp()->keyForMailboxJob(); +    GpgME::Key k; +    GpgME::UserID uid; +    job->exec(mailbox, true, k, uid); +    qDebug() << "UID Name: " << uid.name() << " Mail: " << uid.email() << " id: " << uid.id(); +    qDebug() << "Key fpr: " << k.primaryFingerprint(); +    return 0; +} | 
