libkdenetwork Library API Documentation

kpgpbase5.cpp

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