00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifdef HAVE_CONFIG_H
00034 #include <config.h>
00035 #endif
00036
00037 #include "kpgpkeylistjob.h"
00038
00039 #include <kpgpbase.h>
00040 #include <kpgpkey.h>
00041
00042 #include <gpgmepp/key.h>
00043 #include <gpgmepp/keylistresult.h>
00044
00045 #include <gpgme.h>
00046
00047 #include <qtimer.h>
00048
00049 #include <stdlib.h>
00050 #include <string.h>
00051 #include <assert.h>
00052
00053 Kleo::KpgpKeyListJob::KpgpKeyListJob( Kpgp::Base * pgpBase )
00054 : KeyListJob( 0, "Kleo::KpgpKeyListJob" ),
00055 mPgpBase( pgpBase )
00056 {
00057 }
00058
00059 Kleo::KpgpKeyListJob::~KpgpKeyListJob() {
00060 }
00061
00062
00063 static char *
00064 set_user_id_part (char *tail, const char *buf, size_t len)
00065 {
00066 while (len && (buf[len - 1] == ' ' || buf[len - 1] == '\t'))
00067 len--;
00068 for (; len; len--)
00069 *tail++ = *buf++;
00070 *tail++ = 0;
00071 return tail;
00072 }
00073
00074
00075 static void
00076 parse_user_id (char *src, char **name, char **email,
00077 char **comment, char *tail)
00078 {
00079 const char *start = NULL;
00080 int in_name = 0;
00081 int in_email = 0;
00082 int in_comment = 0;
00083
00084 while (*src)
00085 {
00086 if (in_email)
00087 {
00088 if (*src == '<')
00089
00090 in_email++;
00091 else if (*src == '>')
00092 {
00093 if (!--in_email && !*email)
00094 {
00095 *email = tail;
00096 tail = set_user_id_part (tail, start, src - start);
00097 }
00098 }
00099 }
00100 else if (in_comment)
00101 {
00102 if (*src == '(')
00103 in_comment++;
00104 else if (*src == ')')
00105 {
00106 if (!--in_comment && !*comment)
00107 {
00108 *comment = tail;
00109 tail = set_user_id_part (tail, start, src - start);
00110 }
00111 }
00112 }
00113 else if (*src == '<')
00114 {
00115 if (in_name)
00116 {
00117 if (!*name)
00118 {
00119 *name = tail;
00120 tail = set_user_id_part (tail, start, src - start);
00121 }
00122 in_name = 0;
00123 }
00124 in_email = 1;
00125 start = src + 1;
00126 }
00127 else if (*src == '(')
00128 {
00129 if (in_name)
00130 {
00131 if (!*name)
00132 {
00133 *name = tail;
00134 tail = set_user_id_part (tail, start, src - start);
00135 }
00136 in_name = 0;
00137 }
00138 in_comment = 1;
00139 start = src + 1;
00140 }
00141 else if (!in_name && *src != ' ' && *src != '\t')
00142 {
00143 in_name = 1;
00144 start = src;
00145 }
00146 src++;
00147 }
00148
00149 if (in_name)
00150 {
00151 if (!*name)
00152 {
00153 *name = tail;
00154 tail = set_user_id_part (tail, start, src - start);
00155 }
00156 }
00157
00158
00159 tail--;
00160 if (!*name)
00161 *name = tail;
00162 if (!*email)
00163 *email = tail;
00164 if (!*comment)
00165 *comment = tail;
00166 }
00167
00168 gpgme_user_id_t KpgpUserID2GPGMEUserID( const Kpgp::UserID * kUserId )
00169 {
00170
00171
00172 const QCString text = kUserId->text().utf8();
00173 const int src_len = text.length();
00174
00175 gpgme_user_id_t uid;
00176
00177
00178 uid = (gpgme_user_id_t) malloc( sizeof( *uid ) + 2 * src_len + 3 );
00179 memset( uid, 0, sizeof *uid );
00180 uid->revoked = kUserId->revoked();
00181 uid->invalid = kUserId->invalid();
00182 uid->validity = (gpgme_validity_t) kUserId->validity();
00183
00184 uid->uid = ((char *) uid) + sizeof (*uid);
00185 char *dst = uid->uid;
00186 memcpy( dst, text.data(), src_len + 1 );
00187
00188 dst += src_len + 1;
00189 parse_user_id( uid->uid, &uid->name, &uid->email,
00190 &uid->comment, dst );
00191
00192 return uid;
00193 }
00194
00195 gpgme_subkey_t KpgpSubkey2GPGMESubKey( const Kpgp::Subkey * kSubkey )
00196 {
00197 gpgme_subkey_t subkey;
00198
00199 const QCString fpr = kSubkey->fingerprint();
00200 const unsigned int fpr_len = fpr.length();
00201 const QCString keyId = kSubkey->longKeyID();
00202
00203 subkey = (gpgme_subkey_t) calloc( 1, sizeof( *subkey ) + fpr_len + 1 );
00204 subkey->revoked = kSubkey->revoked();
00205 subkey->expired = kSubkey->expired();
00206 subkey->disabled = kSubkey->disabled();
00207 subkey->invalid = kSubkey->invalid();
00208 subkey->can_encrypt = kSubkey->canEncrypt();
00209 subkey->can_sign = kSubkey->canSign();
00210 subkey->can_certify = kSubkey->canCertify();
00211 subkey->secret = kSubkey->secret();
00212 subkey->pubkey_algo = (gpgme_pubkey_algo_t) kSubkey->keyAlgorithm();
00213 subkey->length = kSubkey->keyLength();
00214 subkey->keyid = subkey->_keyid;
00215 memcpy( subkey->_keyid, keyId.data(), keyId.length() + 1 );
00216 subkey->fpr = ((char *) subkey) + sizeof( *subkey );
00217 memcpy( subkey->fpr, fpr.data(), fpr_len + 1 );
00218 subkey->timestamp = kSubkey->creationDate();
00219 subkey->expires = kSubkey->expirationDate();
00220
00221 return subkey;
00222 }
00223
00224 gpgme_key_t KpgpKey2gpgme_key( const Kpgp::Key * kKey )
00225 {
00226 gpgme_key_t key;
00227
00228 key = (gpgme_key_t) calloc( 1, sizeof( *key ) );
00229 key->revoked = kKey->revoked();
00230 key->expired = kKey->expired();
00231 key->disabled = kKey->disabled();
00232 key->invalid = kKey->invalid();
00233 key->can_encrypt = kKey->canEncrypt();
00234 key->can_sign = kKey->canSign();
00235 key->can_certify = kKey->canCertify();
00236 key->secret = kKey->secret();
00237 key->protocol = GPGME_PROTOCOL_OpenPGP;
00238 key->owner_trust = GPGME_VALIDITY_UNKNOWN;
00239
00240 Kpgp::UserIDList kUserIDs = kKey->userIDs();
00241 for ( Kpgp::UserIDListIterator it( kUserIDs ); it.current(); ++it ) {
00242 gpgme_user_id_t uid = KpgpUserID2GPGMEUserID( *it );
00243 if ( !key->uids )
00244 key->uids = uid;
00245 if ( key->_last_uid )
00246 key->_last_uid->next = uid;
00247 key->_last_uid = uid;
00248 }
00249
00250 Kpgp::SubkeyList kSubkeys = kKey->subkeys();
00251 for ( Kpgp::SubkeyListIterator it( kSubkeys ); it.current(); ++it ) {
00252 gpgme_subkey_t subkey = KpgpSubkey2GPGMESubKey( *it );
00253 if (!key->subkeys)
00254 key->subkeys = subkey;
00255 if (key->_last_subkey)
00256 key->_last_subkey->next = subkey;
00257 key->_last_subkey = subkey;
00258 }
00259
00260 return key;
00261 }
00262
00263 GpgME::Error Kleo::KpgpKeyListJob::start( const QStringList & patterns,
00264 bool secretOnly ) {
00265 mPatterns = patterns;
00266 mSecretOnly = secretOnly;
00267 QTimer::singleShot( 0, this, SLOT( slotDoIt() ) );
00268 return GpgME::Error( 0 );
00269 }
00270
00271 void Kleo::KpgpKeyListJob::slotDoIt() {
00272 std::vector<GpgME::Key> keys;
00273 GpgME::KeyListResult res = exec( mPatterns, mSecretOnly, keys );
00274 for ( std::vector<GpgME::Key>::const_iterator it = keys.begin();
00275 it != keys.end(); ++it )
00276 emit nextKey( *it );
00277 emit done();
00278 emit result( res );
00279 deleteLater();
00280 }
00281
00282 GpgME::KeyListResult Kleo::KpgpKeyListJob::exec( const QStringList & patterns,
00283 bool secretOnly,
00284 std::vector<GpgME::Key> & keys ) {
00285 Kpgp::KeyList kKeys;
00286 if ( secretOnly )
00287 kKeys = mPgpBase->secretKeys( patterns );
00288 else
00289 kKeys = mPgpBase->publicKeys( patterns );
00290
00291 keys.clear();
00292 for ( Kpgp::KeyListIterator it( kKeys ); it.current(); ++it ) {
00293 keys.push_back( GpgME::Key( KpgpKey2gpgme_key(*it), true ) );
00294 }
00295
00296 _gpgme_op_keylist_result res;
00297 res.truncated = 0;
00298 res._unused = 0;
00299
00300 return GpgME::KeyListResult( GpgME::Error( 0 ), res );
00301 }
00302
00303 #include "kpgpkeylistjob.moc"