summaryrefslogtreecommitdiffstats
path: root/certmanager/lib/backends/kpgp/kpgpkeylistjob.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'certmanager/lib/backends/kpgp/kpgpkeylistjob.cpp')
-rw-r--r--certmanager/lib/backends/kpgp/kpgpkeylistjob.cpp303
1 files changed, 303 insertions, 0 deletions
diff --git a/certmanager/lib/backends/kpgp/kpgpkeylistjob.cpp b/certmanager/lib/backends/kpgp/kpgpkeylistjob.cpp
new file mode 100644
index 00000000..4c328ade
--- /dev/null
+++ b/certmanager/lib/backends/kpgp/kpgpkeylistjob.cpp
@@ -0,0 +1,303 @@
+/*
+ kpgpkeylistjob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Ingo Kloecker <kloecker@kde.org>
+
+ Libkleopatra 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.
+
+ Libkleopatra 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "kpgpkeylistjob.h"
+
+#include <kpgpbase.h>
+#include <kpgpkey.h>
+
+#include <gpgmepp/key.h>
+#include <gpgmepp/keylistresult.h>
+
+#include <gpgme.h>
+
+#include <qtimer.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+Kleo::KpgpKeyListJob::KpgpKeyListJob( Kpgp::Base * pgpBase )
+ : KeyListJob( 0, "Kleo::KpgpKeyListJob" ),
+ mPgpBase( pgpBase )
+{
+}
+
+Kleo::KpgpKeyListJob::~KpgpKeyListJob() {
+}
+
+// the following function is a verbatim copy from gpgme/key.c
+static char *
+set_user_id_part (char *tail, const char *buf, size_t len)
+{
+ while (len && (buf[len - 1] == ' ' || buf[len - 1] == '\t'))
+ len--;
+ for (; len; len--)
+ *tail++ = *buf++;
+ *tail++ = 0;
+ return tail;
+}
+
+// the following function is a verbatim copy from gpgme/key.c
+static void
+parse_user_id (char *src, char **name, char **email,
+ char **comment, char *tail)
+{
+ const char *start = NULL;
+ int in_name = 0;
+ int in_email = 0;
+ int in_comment = 0;
+
+ while (*src)
+ {
+ if (in_email)
+ {
+ if (*src == '<')
+ /* Not legal but anyway. */
+ in_email++;
+ else if (*src == '>')
+ {
+ if (!--in_email && !*email)
+ {
+ *email = tail;
+ tail = set_user_id_part (tail, start, src - start);
+ }
+ }
+ }
+ else if (in_comment)
+ {
+ if (*src == '(')
+ in_comment++;
+ else if (*src == ')')
+ {
+ if (!--in_comment && !*comment)
+ {
+ *comment = tail;
+ tail = set_user_id_part (tail, start, src - start);
+ }
+ }
+ }
+ else if (*src == '<')
+ {
+ if (in_name)
+ {
+ if (!*name)
+ {
+ *name = tail;
+ tail = set_user_id_part (tail, start, src - start);
+ }
+ in_name = 0;
+ }
+ in_email = 1;
+ start = src + 1;
+ }
+ else if (*src == '(')
+ {
+ if (in_name)
+ {
+ if (!*name)
+ {
+ *name = tail;
+ tail = set_user_id_part (tail, start, src - start);
+ }
+ in_name = 0;
+ }
+ in_comment = 1;
+ start = src + 1;
+ }
+ else if (!in_name && *src != ' ' && *src != '\t')
+ {
+ in_name = 1;
+ start = src;
+ }
+ src++;
+ }
+
+ if (in_name)
+ {
+ if (!*name)
+ {
+ *name = tail;
+ tail = set_user_id_part (tail, start, src - start);
+ }
+ }
+
+ /* Let unused parts point to an EOS. */
+ tail--;
+ if (!*name)
+ *name = tail;
+ if (!*email)
+ *email = tail;
+ if (!*comment)
+ *comment = tail;
+}
+
+gpgme_user_id_t KpgpUserID2GPGMEUserID( const Kpgp::UserID * kUserId )
+{
+ // inspired by _gpgme_key_append_name
+
+ const QCString text = kUserId->text().utf8();
+ const int src_len = text.length();
+
+ gpgme_user_id_t uid;
+ /* Allocate enough memory for the _gpgme_user_id struct, for the actual user
+ id (the text) and for the parsed version. */
+ uid = (gpgme_user_id_t) malloc( sizeof( *uid ) + 2 * src_len + 3 );
+ memset( uid, 0, sizeof *uid );
+ uid->revoked = kUserId->revoked();
+ uid->invalid = kUserId->invalid();
+ uid->validity = (gpgme_validity_t) kUserId->validity();
+
+ uid->uid = ((char *) uid) + sizeof (*uid);
+ char *dst = uid->uid;
+ memcpy( dst, text.data(), src_len + 1 );
+
+ dst += src_len + 1;
+ parse_user_id( uid->uid, &uid->name, &uid->email,
+ &uid->comment, dst );
+
+ return uid;
+}
+
+gpgme_subkey_t KpgpSubkey2GPGMESubKey( const Kpgp::Subkey * kSubkey )
+{
+ gpgme_subkey_t subkey;
+
+ const QCString fpr = kSubkey->fingerprint();
+ const unsigned int fpr_len = fpr.length();
+ const QCString keyId = kSubkey->longKeyID();
+
+ subkey = (gpgme_subkey_t) calloc( 1, sizeof( *subkey ) + fpr_len + 1 );
+ subkey->revoked = kSubkey->revoked();
+ subkey->expired = kSubkey->expired();
+ subkey->disabled = kSubkey->disabled();
+ subkey->invalid = kSubkey->invalid();
+ subkey->can_encrypt = kSubkey->canEncrypt();
+ subkey->can_sign = kSubkey->canSign();
+ subkey->can_certify = kSubkey->canCertify();
+ subkey->secret = kSubkey->secret();
+ subkey->pubkey_algo = (gpgme_pubkey_algo_t) kSubkey->keyAlgorithm();
+ subkey->length = kSubkey->keyLength();
+ subkey->keyid = subkey->_keyid;
+ memcpy( subkey->_keyid, keyId.data(), keyId.length() + 1 );
+ subkey->fpr = ((char *) subkey) + sizeof( *subkey );
+ memcpy( subkey->fpr, fpr.data(), fpr_len + 1 );
+ subkey->timestamp = kSubkey->creationDate();
+ subkey->expires = kSubkey->expirationDate();
+
+ return subkey;
+}
+
+gpgme_key_t KpgpKey2gpgme_key( const Kpgp::Key * kKey )
+{
+ gpgme_key_t key;
+
+ key = (gpgme_key_t) calloc( 1, sizeof( *key ) );
+ key->revoked = kKey->revoked();
+ key->expired = kKey->expired();
+ key->disabled = kKey->disabled();
+ key->invalid = kKey->invalid();
+ key->can_encrypt = kKey->canEncrypt();
+ key->can_sign = kKey->canSign();
+ key->can_certify = kKey->canCertify();
+ key->secret = kKey->secret();
+ key->protocol = GPGME_PROTOCOL_OpenPGP;
+ key->owner_trust = GPGME_VALIDITY_UNKNOWN; // FIXME?
+
+ Kpgp::UserIDList kUserIDs = kKey->userIDs();
+ for ( Kpgp::UserIDListIterator it( kUserIDs ); it.current(); ++it ) {
+ gpgme_user_id_t uid = KpgpUserID2GPGMEUserID( *it );
+ if ( !key->uids )
+ key->uids = uid;
+ if ( key->_last_uid )
+ key->_last_uid->next = uid;
+ key->_last_uid = uid;
+ }
+
+ Kpgp::SubkeyList kSubkeys = kKey->subkeys();
+ for ( Kpgp::SubkeyListIterator it( kSubkeys ); it.current(); ++it ) {
+ gpgme_subkey_t subkey = KpgpSubkey2GPGMESubKey( *it );
+ if (!key->subkeys)
+ key->subkeys = subkey;
+ if (key->_last_subkey)
+ key->_last_subkey->next = subkey;
+ key->_last_subkey = subkey;
+ }
+
+ return key;
+}
+
+GpgME::Error Kleo::KpgpKeyListJob::start( const QStringList & patterns,
+ bool secretOnly ) {
+ mPatterns = patterns;
+ mSecretOnly = secretOnly;
+ QTimer::singleShot( 0, this, SLOT( slotDoIt() ) );
+ return GpgME::Error( 0 );
+}
+
+void Kleo::KpgpKeyListJob::slotDoIt() {
+ std::vector<GpgME::Key> keys;
+ GpgME::KeyListResult res = exec( mPatterns, mSecretOnly, keys );
+ for ( std::vector<GpgME::Key>::const_iterator it = keys.begin();
+ it != keys.end(); ++it )
+ emit nextKey( *it );
+ emit done();
+ emit result( res );
+ deleteLater();
+}
+
+GpgME::KeyListResult Kleo::KpgpKeyListJob::exec( const QStringList & patterns,
+ bool secretOnly,
+ std::vector<GpgME::Key> & keys ) {
+ Kpgp::KeyList kKeys;
+ if ( secretOnly )
+ kKeys = mPgpBase->secretKeys( patterns );
+ else
+ kKeys = mPgpBase->publicKeys( patterns );
+
+ keys.clear();
+ for ( Kpgp::KeyListIterator it( kKeys ); it.current(); ++it ) {
+ keys.push_back( GpgME::Key( KpgpKey2gpgme_key(*it), true ) );
+ }
+
+ _gpgme_op_keylist_result res;
+ res.truncated = 0; // key list is not truncated
+ res._unused = 0;
+
+ return GpgME::KeyListResult( GpgME::Error( 0 ), res );
+}
+
+#include "kpgpkeylistjob.moc"