• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdepim
  • Sitemap
  • Contact Us
 

libkpgp

kpgpbase5.cpp

Go to the documentation of this file.
00001 /*
00002     kpgpbase5.cpp
00003 
00004     Copyright (C) 2001,2002 the KPGP authors
00005     See file AUTHORS.kpgp for details
00006 
00007     This file is part of KPGP, the KDE PGP/GnuPG support library.
00008 
00009     KPGP is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software Foundation,
00016     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
00017  */
00018 
00019 
00020 #include "kpgpbase.h"
00021 #include "kpgp.h"
00022 
00023 #include <string.h> /* strncmp */
00024 #include <assert.h>
00025 
00026 #include <QRegExp>
00027 #include <QDateTime>
00028 //Added by qt3to4:
00029 #include <QByteArray>
00030 
00031 #include <klocale.h>
00032 #include <kshell.h>
00033 #include <kdebug.h>
00034 
00035 
00036 namespace Kpgp {
00037 
00038 Base5::Base5()
00039   : Base()
00040 {
00041 }
00042 
00043 
00044 Base5::~Base5()
00045 {
00046 }
00047 
00048 
00049 int
00050 Base5::encrypt( Block& block, const KeyIDList& recipients )
00051 {
00052   return encsign( block, recipients, 0 );
00053 }
00054 
00055 
00056 int
00057 Base5::clearsign( Block& block, const char *passphrase )
00058 {
00059   return encsign( block, KeyIDList(), passphrase );
00060 }
00061 
00062 
00063 int
00064 Base5::encsign( Block& block, const KeyIDList& recipients,
00065                 const char *passphrase )
00066 {
00067   QByteArray cmd;
00068   int exitStatus = 0;
00069   int index;
00070   // used to work around a bug in pgp5. pgp5 treats files
00071   // with non ascii chars (umlauts, etc...) as binary files, but
00072   // we want a clear signature
00073   bool signonly = false;
00074 
00075   if(!recipients.isEmpty() && passphrase != 0)
00076     cmd = "pgpe +batchmode -afts ";
00077   else if(!recipients.isEmpty())
00078     cmd = "pgpe +batchmode -aft ";
00079   else if(passphrase != 0)
00080   {
00081     cmd = "pgps +batchmode -abft ";
00082     signonly = true;
00083   }
00084   else
00085   {
00086     errMsg = i18n("Neither recipients nor passphrase specified.");
00087     return OK;
00088   }
00089 
00090   if(passphrase != 0)
00091     cmd += addUserId();
00092 
00093   if(!recipients.isEmpty())
00094   {
00095     if(Module::getKpgp()->encryptToSelf())
00096     {
00097       cmd += " -r 0x";
00098       cmd += Module::getKpgp()->user();
00099     }
00100 
00101     for( KeyIDList::ConstIterator it = recipients.begin();
00102          it != recipients.end(); ++it ) {
00103       cmd += " -r 0x";
00104       cmd += (*it);
00105     }
00106   }
00107 
00108   clear();
00109   input = block.text();
00110 
00111   if (signonly)
00112   {
00113     input.append("\n");
00114     //input.replace(QRegExp("[ \t]+\n"), "\n");   //strip trailing whitespace
00115     input = input.trimmed();   // PORT: check if that change was ok!
00116   }
00117   //We have to do this otherwise it's all in vain
00118 
00119   exitStatus = run(cmd.data(), passphrase);
00120   block.setError( error );
00121 
00122   if(exitStatus != 0)
00123     status = ERROR;
00124 
00125   // now parse the returned info
00126   if(error.contains("Cannot unlock private key") )
00127   {
00128     errMsg = i18n("The passphrase you entered is invalid.");
00129     status |= ERROR;
00130     status |= BADPHRASE;
00131   }
00132 //if(!ignoreUntrusted)
00133 //{
00134     QByteArray aStr;
00135     index = -1;
00136     while((index = error.indexOf("WARNING: The above key",index+1)) != -1 )
00137     {
00138       int index2 = error.indexOf("But you previously",index);
00139       int index3 = error.indexOf("WARNING: The above key",index+1);
00140       if(index2 == -1 || (index2 > index3 && index3 != -1))
00141       {
00142     // the key wasn't valid, no encryption to this person
00143     // extract the person
00144     index2 = error.indexOf('\n',index);
00145     index3 = error.indexOf('\n',index2+1);
00146     aStr += error.mid(index2+1, index3-index2-1);
00147     aStr += ", ";
00148       }
00149     }
00150     if(!aStr.isEmpty())
00151     {
00152       aStr.truncate(aStr.length()-2);
00153       if(error.contains("No valid keys found") )
00154     errMsg = i18n("The key(s) you want to encrypt your message "
00155               "to are not trusted. No encryption done.");
00156       else
00157     errMsg = i18n("The following key(s) are not trusted:\n%1\n"
00158                       "Their owner(s) will not be able to decrypt the message.",
00159               QString::fromLocal8Bit( aStr ));
00160       status |= ERROR;
00161       status |= BADKEYS;
00162     }
00163 //}
00164   if((index = error.indexOf("No encryption keys found for")) != -1 )
00165   {
00166     index = error.indexOf(':',index);
00167     int index2 = error.indexOf('\n',index);
00168 
00169     errMsg = i18n("Missing encryption key(s) for:\n%1",
00170        QString::fromLocal8Bit(error.mid(index,index2-index)));
00171 //    errMsg = QString("Missing encryption key(s) for: %1")
00172 //      .arg(error.mid(index,index2-index));
00173     status |= ERROR;
00174     status |= MISSINGKEY;
00175   }
00176 
00177   if(signonly) {
00178     // dash-escape the input
00179     if (input[0] == '-')
00180       input = "- " + input;
00181     for ( int idx = 0 ; (idx = input.indexOf("\n-", idx)) != -1 ; idx += 4 )
00182       input.replace(idx, 2, "\n- -");
00183 
00184     output = "-----BEGIN PGP SIGNED MESSAGE-----\n\n" + input + '\n' + output;
00185   }
00186 
00187   block.setProcessedText( output );
00188   block.setStatus( status );
00189   return status;
00190 }
00191 
00192 
00193 int
00194 Base5::decrypt( Block& block, const char *passphrase )
00195 {
00196   int exitStatus = 0;
00197 
00198   clear();
00199   input = block.text();
00200   exitStatus = run("pgpv -f +batchmode=1", passphrase);
00201   if( !output.isEmpty() )
00202     block.setProcessedText( output );
00203   block.setError( error );
00204 
00205   if(exitStatus == -1) {
00206     errMsg = i18n("Error running PGP");
00207     status = ERROR;
00208     block.setStatus( status );
00209     return status;
00210   }
00211 
00212   // lets parse the returned information.
00213   int index;
00214 
00215   index = error.indexOf("Cannot decrypt message");
00216   if(index != -1)
00217   {
00218     //kDebug( 5326 ) <<"message is encrypted";
00219     status |= ENCRYPTED;
00220 
00221     // ok. we have an encrypted message. Is the passphrase bad,
00222     // or do we not have the secret key?
00223     if(error.contains("Need a pass phrase") )
00224     {
00225       if(passphrase != 0)
00226       {
00227     errMsg = i18n("Bad passphrase; could not decrypt.");
00228     kDebug( 5326 ) <<"Base: passphrase is bad";
00229     status |= BADPHRASE;
00230     status |= ERROR;
00231       }
00232     }
00233     else
00234     {
00235       // we don't have the secret key
00236       status |= NO_SEC_KEY;
00237       status |= ERROR;
00238       errMsg = i18n("You do not have the secret key needed to decrypt this message.");
00239       kDebug( 5326 ) <<"Base: no secret key for this message";
00240     }
00241     // check for persons
00242 #if 0
00243     // ##### FIXME: This information is anyway currently not used
00244     //       I'll change it to always determine the recipients.
00245     index = error.indexOf("can only be decrypted by:");
00246     if(index != -1)
00247     {
00248       index = error.indexOf('\n',index);
00249       int end = error.indexOf("\n\n",index);
00250 
00251       mRecipients.clear();
00252       int index2;
00253       while( (index2 = error.indexOf('\n',index+1)) <= end )
00254       {
00255     QByteArray item = error.mid(index+1,index2-index-1);
00256     item.trimmed();
00257     mRecipients.append(item);
00258     index = index2;
00259       }
00260     }
00261 #endif
00262   }
00263   index = error.indexOf("Good signature");
00264   if(index != -1)
00265   {
00266     //kDebug( 5326 ) <<"good signature";
00267     status |= SIGNED;
00268     status |= GOODSIG;
00269 
00270     // get key ID of signer
00271     index = error.indexOf("Key ID ", index) + 7;
00272     block.setSignatureKeyId( error.mid(index, 8) );
00273 
00274     // get signer
00275     index = error.indexOf('"',index) + 1;
00276     int index2 = error.indexOf('"', index);
00277     block.setSignatureUserId( error.mid(index, index2-index) );
00278 
00280     block.setSignatureDate( "" );
00281   }
00282   index = error.indexOf("BAD signature");
00283   if(index != -1)
00284   {
00285     //kDebug( 5326 ) <<"BAD signature";
00286     status |= SIGNED;
00287     status |= ERROR;
00288 
00289     // get key ID of signer
00290     index = error.indexOf("Key ID ", index) + 7;
00291     block.setSignatureKeyId( error.mid(index, 8) );
00292 
00293     // get signer
00294     index = error.indexOf('"',index) + 1;
00295     int index2 = error.indexOf('"', index);
00296     block.setSignatureUserId( error.mid(index, index2-index) );
00297 
00299     block.setSignatureDate( "" );
00300   }
00301   index = error.indexOf("Signature by unknown key");
00302   if(index != -1)
00303   {
00304     index = error.indexOf("keyid: 0x",index) + 9;
00305     block.setSignatureKeyId( error.mid(index, 8) );
00306     block.setSignatureUserId( QString() );
00307     // FIXME: not a very good solution...
00308     status |= SIGNED;
00309     status |= GOODSIG;
00310 
00312     block.setSignatureDate( "" );
00313   }
00314 
00315   //kDebug( 5326 ) <<"status =" << status;
00316   block.setStatus( status );
00317   return status;
00318 }
00319 
00320 
00321 Key*
00322 Base5::readPublicKey( const KeyID& keyId, const bool readTrust, Key* key )
00323 {
00324   int exitStatus = 0;
00325 
00326   status = 0;
00327   exitStatus = run( "pgpk -ll 0x" + keyId, 0, true );
00328 
00329   if(exitStatus != 0) {
00330     status = ERROR;
00331     return 0;
00332   }
00333 
00334   key = parseSingleKey( output, key );
00335 
00336   if( key == 0 )
00337   {
00338     return 0;
00339   }
00340 
00341   if( readTrust )
00342   {
00343     exitStatus = run( "pgpk -c 0x" + keyId, 0, true );
00344 
00345     if(exitStatus != 0) {
00346       status = ERROR;
00347       return 0;
00348     }
00349 
00350     parseTrustDataForKey( key, output );
00351   }
00352 
00353   return key;
00354 }
00355 
00356 
00357 KeyList
00358 Base5::publicKeys( const QStringList & patterns )
00359 {
00360   int exitStatus = 0;
00361 
00362   QByteArray cmd = "pgpk -ll";
00363   for ( QStringList::ConstIterator it = patterns.begin();
00364         it != patterns.end(); ++it ) {
00365     cmd += ' ';
00366     cmd += KShell::quoteArg( *it ).toLocal8Bit();
00367   }
00368   status = 0;
00369   exitStatus = run( cmd, 0, true );
00370 
00371   if(exitStatus != 0) {
00372     status = ERROR;
00373     return KeyList();
00374   }
00375 
00376   // now we need to parse the output for public keys
00377   KeyList keys = parseKeyList( output, false );
00378 
00379   // sort the list of public keys
00380   keys.sort();
00381 
00382   return keys;
00383 }
00384 
00385 
00386 KeyList
00387 Base5::secretKeys( const QStringList & patterns )
00388 {
00389   int exitStatus = 0;
00390 
00391   status = 0;
00392   QByteArray cmd = "pgpk -ll";
00393   for ( QStringList::ConstIterator it = patterns.begin();
00394         it != patterns.end(); ++it ) {
00395     cmd += ' ';
00396     cmd += KShell::quoteArg( *it ).toLocal8Bit();
00397   }
00398   status = 0;
00399   exitStatus = run( cmd, 0, true );
00400 
00401   if(exitStatus != 0) {
00402     status = ERROR;
00403     return KeyList();
00404   }
00405 
00406   // now we need to parse the output for secret keys
00407   KeyList keys = parseKeyList( output, true );
00408 
00409   // sort the list of public keys
00410   keys.sort();
00411 
00412   return keys;
00413 }
00414 
00415 
00416 QByteArray Base5::getAsciiPublicKey(const KeyID& keyID)
00417 {
00418   int exitStatus = 0;
00419 
00420   if (keyID.isEmpty())
00421     return QByteArray();
00422 
00423   status = 0;
00424   exitStatus = run( "pgpk -xa 0x" + keyID, 0, true );
00425 
00426   if(exitStatus != 0) {
00427     status = ERROR;
00428     return QByteArray();
00429   }
00430 
00431   return output;
00432 }
00433 
00434 
00435 int
00436 Base5::signKey(const KeyID& keyID, const char *passphrase)
00437 {
00438   QByteArray cmd;
00439   int exitStatus = 0;
00440 
00441   if(passphrase == 0) return false;
00442 
00443   cmd = "pgpk -s -f +batchmode=1 0x";
00444   cmd += keyID;
00445   cmd += addUserId();
00446 
00447   status = 0;
00448   exitStatus = run(cmd.data(), passphrase);
00449 
00450   if (exitStatus != 0)
00451     status = ERROR;
00452 
00453   return status;
00454 }
00455 
00456 //-- private functions --------------------------------------------------------
00457 
00458 Key*
00459 Base5::parseKeyData( const QByteArray& output, int& offset, Key* key /* = 0 */ )
00460 // This function parses the data for a single key which is output by PGP 5
00461 // with the following command line:
00462 //   pgpk -ll
00463 // It expects the key data to start at offset and returns the start of
00464 // the next key's data in offset.
00465 {
00466   if( ( strncmp( output.data() + offset, "pub", 3 ) != 0 ) &&
00467       ( strncmp( output.data() + offset, "sec", 3 ) != 0 ) )
00468   {
00469     kDebug( 5326 ) <<"Unknown key type or corrupt key data.";
00470     return 0;
00471   }
00472 
00473   if( key == 0 )
00474     key = new Key();
00475   else
00476     key->clear();
00477 
00478   Subkey *subkey = 0;
00479   bool primaryKey = true;
00480 
00481   while( true )
00482   {
00483     int eol;
00484 
00485     // search the end of the current line
00486     eol = output.indexOf( '\n', offset );
00487     if( ( eol == -1 ) || ( eol == offset ) )
00488       break;
00489 
00490     //kDebug( 5326 ) <<"Parsing:" << output.mid(offset, eol-offset);
00491 
00492     if( !strncmp( output.data() + offset, "pub", 3 ) ||
00493         !strncmp( output.data() + offset, "sec", 3 ) ||
00494         !strncmp( output.data() + offset, "sub", 3 ) )
00495     { // line contains key data
00496       //kDebug( 5326 )<<"Key data:";
00497       int pos, pos2;
00498 
00499       subkey = new Subkey( "", false );
00500       key->addSubkey( subkey );
00501 
00502       // Key Flags
00503       /* From the PGP 5 manual page for pgpk:
00504          Following this column is a single  character  which
00505          describes other attributes of the object:
00506 
00507          @  The object is disabled
00508          +  The object is axiomatically trusted  (i.e.,  it's
00509             your key)
00510       */
00511       switch( output[offset+3] )
00512       {
00513       case ' ': // nothing special
00514         break;
00515       case '@': // disabled key
00516         subkey->setDisabled( true );
00517         key->setDisabled( true );
00518         break;
00519       default: // all other flags are ignored
00520         //kDebug( 5326 ) <<"Unknown key flag.";
00521         ;
00522       }
00523 
00524       // Key Length
00525       pos = offset + 4;
00526       while( output[pos] == ' ' )
00527         pos++;
00528       pos2 = output.indexOf( ' ', pos );
00529       subkey->setKeyLength( output.mid( pos, pos2-pos ).toUInt() );
00530       //kDebug( 5326 ) <<"Key Length:"<<subkey->keyLength();
00531 
00532       // Key ID
00533       pos = pos2 + 1;
00534       while( output[pos] == ' ' )
00535         pos++;
00536       pos += 2; // skip the '0x'
00537       pos2 = output.indexOf( ' ', pos );
00538       subkey->setKeyID( output.mid( pos, pos2-pos ) );
00539       //kDebug( 5326 ) <<"Key ID:"<<subkey->keyID();
00540 
00541       // Creation Date
00542       pos = pos2 + 1;
00543       while( output[pos] == ' ' )
00544         pos++;
00545       pos2 = output.indexOf( ' ', pos );
00546       int year = output.mid( pos, 4 ).toInt();
00547       int month = output.mid( pos+5, 2 ).toInt();
00548       int day = output.mid( pos+8, 2 ).toInt();
00549       QDateTime dt( QDate( year, month, day ), QTime( 00, 00 ) );
00550       QDateTime epoch( QDate( 1970, 01, 01 ), QTime( 00, 00 ) );
00551       // The calculated creation date isn't exactly correct because QDateTime
00552       // doesn't know anything about timezones and always assumes local time
00553       // although epoch is of course UTC. But as PGP 5 anyway doesn't print
00554       // the time this doesn't matter too much.
00555       subkey->setCreationDate( epoch.secsTo( dt ) );
00556 
00557       // Expiration Date
00558       // if the primary key has been revoked the expiration date is not printed
00559       if( primaryKey || !key->revoked() )
00560       {
00561         pos = pos2 + 1;
00562         while( output[pos] == ' ' )
00563           pos++;
00564         pos2 = output.indexOf( ' ', pos );
00565         if( output[pos] == '-' )
00566         { // key doesn't expire
00567           subkey->setExpirationDate( -1 );
00568         }
00569         else if( !strncmp( output.data() + pos, "*REVOKED*", 9 ) )
00570         { // key has been revoked
00571           subkey->setRevoked( true );
00572           key->setRevoked( true );
00573         }
00574         else
00575         {
00576           int year = output.mid( pos, 4 ).toInt();
00577           int month = output.mid( pos+5, 2 ).toInt();
00578           int day = output.mid( pos+8, 2 ).toInt();
00579           QDateTime dt( QDate( year, month, day ), QTime( 00, 00 ) );
00580           subkey->setCreationDate( epoch.secsTo( dt ) );
00581           // has the key already expired?
00582           if( QDateTime::currentDateTime() >= dt )
00583           {
00584             subkey->setExpired( true );
00585             key->setExpired( true );
00586           }
00587         }
00588       }
00589       else if( key->revoked() )
00590         subkey->setRevoked( true );
00591 
00592       // Key algorithm (RSA, DSS, Diffie-Hellman)
00593       bool sign = false;
00594       bool encr = false;
00595       pos = pos2 + 1;
00596       while( output[pos] == ' ' )
00597         pos++;
00598       pos2 = output.indexOf( ' ', pos );
00599       if( !strncmp( output.data() + pos, "RSA", 3 ) )
00600       {
00601         sign = true;
00602         encr = true;
00603       }
00604       else if( !strncmp( output.data() + pos, "DSS", 3 ) )
00605         sign = true;
00606       else if( !strncmp( output.data() + pos, "Diffie-Hellman", 14 ) )
00607         encr = true;
00608       else
00609         kDebug( 5326 )<<"Unknown key algorithm";
00610 
00611       // set key capabilities of the subkey
00612       subkey->setCanEncrypt( encr );
00613       subkey->setCanSign( sign );
00614       subkey->setCanCertify( sign );
00615 
00616       if( primaryKey )
00617       {
00618         // Global key capabilities
00619         bool canSign = false;
00620         bool canEncr = false;
00621         pos = pos2 + 1;
00622         while( output[pos] == ' ' )
00623           pos++;
00624         pos2 = eol;
00625         if( !strncmp( output.data() + pos, "Sign & Encrypt", 14 ) )
00626         {
00627           canSign = true;
00628           canEncr = true;
00629         }
00630         else if( !strncmp( output.data() + pos, "Sign only", 9 ) )
00631           canSign = true;
00632         else if( !strncmp( output.data() + pos, "Encrypt only", 12 ) )
00633           canEncr = true;
00634         else
00635           kDebug( 5326 )<<"Unknown key capability";
00636 
00637         // set the global key capabilities
00638         if( !key->expired() && !key->revoked() )
00639         {
00640           key->setCanEncrypt( canEncr );
00641           key->setCanSign( canSign );
00642           key->setCanCertify( canSign );
00643         }
00644         //kDebug( 5326 )<<"Key capabilities:"<<(key->canEncrypt()?"E":"")<<(key->canSign()?"SC":"");
00645         primaryKey = false;
00646       }
00647     }
00648     else if( !strncmp( output.data() + offset, "f16", 3 ) ||
00649              !strncmp( output.data() + offset, "f20", 3 ) )
00650     { // line contains a fingerprint
00651       /* Examples:
00652          f16    Fingerprint16 = DE 2A 77 08 78 64 7C 42  72 75 B1 A7 3E 42 3F 79
00653          f20    Fingerprint20 = 226F 4B63 6DA2 7389 91D1  2A49 D58A 3EC1 5214 181E
00654 
00655        */
00656       int pos = output.indexOf( '=', offset+3 ) + 2;
00657       QByteArray fingerprint = output.mid( pos, eol-pos );
00658       // remove white space from the fingerprint
00659       for ( int idx = 0 ; (idx = fingerprint.indexOf(' ', idx)) != -1 ; )
00660     fingerprint.replace( idx, 1, "" );
00661       assert( subkey != 0 );
00662       subkey->setFingerprint( fingerprint );
00663       //kDebug( 5326 )<<"Fingerprint:"<<fingerprint;
00664     }
00665     else if( !strncmp( output.data() + offset, "uid", 3 ) )
00666     { // line contains a uid
00667       int pos = offset+5;
00668       QByteArray uid = output.mid( pos, eol-pos );
00669       key->addUserID( uid );
00670       // displaying of uids which contain non-ASCII characters is broken in
00671       // PGP 5.0i; it shows these characters as \ooo and truncates the uid
00672       // because it doesn't take the 3 extra characters per non-ASCII char
00673       // into account. Example (with an UTF-8 encoded &ouml;):
00674       // uid  Ingo Kl\303\266cker <ingo.kloecker@epo
00675       // because of this and because we anyway don't know which charset was
00676       // used to encode the uid we don't try to decode it
00677     }
00678     else if ( !strncmp( output.data() + offset, "sig", 3 ) ||
00679               !strncmp( output.data() + offset, "SIG", 3 ) ||
00680               !strncmp( output.data() + offset, "ret", 3 ) )
00681     { // line contains a signature
00682       // SIG = sig with own key; ret = sig with revoked key
00683       // we ignore it for now
00684     }
00685 
00686     offset = eol + 1;
00687   }
00688 
00689   return key;
00690 }
00691 
00692 
00693 Key*
00694 Base5::parseSingleKey( const QByteArray& output, Key* key /* = 0 */ )
00695 {
00696   int offset;
00697 
00698   // search start of header line
00699   if( !strncmp( output.data(), "Type Bits", 9 ) )
00700     offset = 0;
00701   else
00702   {
00703     offset = output.indexOf( "\nType Bits" ) + 1;
00704     if( offset == 0 )
00705       return 0;
00706   }
00707 
00708   // key data begins in the next line
00709   offset = output.indexOf( '\n', offset ) + 1;
00710   if( offset == -1 )
00711     return 0;
00712 
00713   key = parseKeyData( output, offset, key );
00714 
00715   //kDebug( 5326 ) <<"finished parsing keys";
00716 
00717   return key;
00718 }
00719 
00720 
00721 KeyList
00722 Base5::parseKeyList( const QByteArray& output, bool onlySecretKeys )
00723 {
00724   KeyList keys;
00725   Key *key = 0;
00726   int offset;
00727 
00728   // search start of header line
00729   if( !strncmp( output.data(), "Type Bits", 9 ) )
00730     offset = 0;
00731   else
00732   {
00733     offset = output.indexOf( "\nType Bits" ) + 1;
00734     if( offset == 0 )
00735       return keys;
00736   }
00737 
00738   // key data begins in the next line
00739   offset = output.indexOf( '\n', offset ) + 1;
00740   if( offset == -1 )
00741     return keys;
00742 
00743   do
00744   {
00745     key = parseKeyData( output, offset );
00746     if( key != 0 )
00747     {
00748       // if only secret keys should be read test if the key is secret
00749       if( !onlySecretKeys || !key->secret() )
00750         keys.append( key );
00751       // skip the blank line which separates the keys
00752       offset++;
00753     }
00754   }
00755   while( key != 0 );
00756 
00757   //kDebug( 5326 ) <<"finished parsing keys";
00758 
00759   return keys;
00760 }
00761 
00762 
00763 void
00764 Base5::parseTrustDataForKey( Key* key, const QByteArray& str )
00765 {
00766   if( ( key == 0 ) || str.isEmpty() )
00767     return;
00768 
00769   QByteArray keyID = "0x" + key->primaryKeyID();
00770   UserIDList userIDs = key->userIDs();
00771 
00772   // search the start of the trust data
00773   int offset = str.indexOf( "\n\n  KeyID" ) + 9;
00774   if( offset == -1 + 9 )
00775     return;
00776 
00777   offset = str.indexOf( '\n', offset ) + 1;
00778   if( offset == -1 + 1 )
00779     return;
00780 
00781   bool ultimateTrust = false;
00782   if( !strncmp( str.data() + offset+13, "ultimate", 8 ) )
00783     ultimateTrust = true;
00784 
00785   while( true )
00786   { // loop over all trust information about this key
00787 
00788     int eol;
00789 
00790     // search the end of the current line
00791     if( ( eol = str.indexOf( '\n', offset ) ) == -1 )
00792       break;
00793 
00794     if( str[offset+23] != ' ' )
00795     { // line contains a validity value for a user ID
00796 
00797       // determine the validity
00798       Validity validity = KPGP_VALIDITY_UNKNOWN;
00799       if( !strncmp( str.data() + offset+23, "complete", 8 ) )
00800         if( ultimateTrust )
00801           validity = KPGP_VALIDITY_ULTIMATE;
00802         else
00803           validity = KPGP_VALIDITY_FULL;
00804       else if( !strncmp( str.data() + offset+23, "marginal", 8 ) )
00805         validity = KPGP_VALIDITY_MARGINAL;
00806       else if( !strncmp( str.data() + offset+23, "invalid", 7 ) )
00807         validity = KPGP_VALIDITY_UNDEFINED;
00808 
00809       // determine the user ID
00810       int pos = offset + 33;
00811       QString uid = str.mid( pos, eol-pos );
00812 
00813       // set the validity of the corresponding user ID
00814       for( UserIDListIterator it( userIDs ); it.current(); ++it )
00815         if( (*it)->text() == uid )
00816         {
00817           kDebug( 5326 )<<"Setting the validity of"<<uid<<" to"<<validity;
00818           (*it)->setValidity( validity );
00819           break;
00820         }
00821     }
00822 
00823     offset = eol + 1;
00824   }
00825 }
00826 
00827 
00828 } // namespace Kpgp

libkpgp

Skip menu "libkpgp"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdepim

Skip menu "kdepim"
  • akonadi
  •   clients
  •   kabc
  •   kcal
  •   kcm
  • akregator
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt
  • kdgantt1
  • kjots
  • kleopatra
  • kmail
  • kmobiletools
  • knode
  • knotes
  • kontact
  • kontactinterfaces
  • korganizer
  •   korgac
  • kpilot
  • ktimetracker
  • libkdepim
  • libkholidays
  • libkleo
  • libkpgp
  • maildir
Generated for kdepim by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal