30 #include <tqdatetime.h>
32 #include <tdelocale.h>
33 #include <tdeprocess.h>
51 Base5::encrypt( Block& block,
const KeyIDList& recipients )
53 return encsign( block, recipients, 0 );
58 Base5::clearsign( Block& block,
const TQString &passphrase )
60 return encsign( block, KeyIDList(), passphrase );
65 Base5::encsign( Block& block,
const KeyIDList& recipients,
66 const TQString &passphrase )
74 bool signonly =
false;
76 if (!recipients.isEmpty() && !passphrase.isEmpty())
77 cmd =
"pgpe +batchmode -afts ";
78 else if(!recipients.isEmpty())
79 cmd =
"pgpe +batchmode -aft ";
80 else if (!passphrase.isEmpty())
82 cmd =
"pgps +batchmode -abft ";
87 errMsg = i18n(
"Neither recipients nor passphrase specified.");
91 if (!passphrase.isEmpty())
94 if(!recipients.isEmpty())
96 if(Module::getKpgp()->encryptToSelf())
99 cmd += Module::getKpgp()->user();
102 for( KeyIDList::ConstIterator it = recipients.begin();
103 it != recipients.end(); ++it ) {
110 input = block.text();
115 input.replace(TQRegExp(
"[ \t]+\n"),
"\n");
119 exitStatus = run(cmd.data(), passphrase);
120 block.setError( error );
126 if(error.find(
"Cannot unlock private key") != -1)
128 errMsg = i18n(
"The passphrase you entered is invalid.");
136 while((index = error.find(
"WARNING: The above key",index+1)) != -1)
138 int index2 = error.find(
"But you previously",index);
139 int index3 = error.find(
"WARNING: The above key",index+1);
140 if(index2 == -1 || (index2 > index3 && index3 != -1))
144 index2 = error.find(
'\n',index);
145 index3 = error.find(
'\n',index2+1);
146 aStr += error.mid(index2+1, index3-index2-1);
152 aStr.truncate(aStr.length()-2);
153 if(error.find(
"No valid keys found") != -1)
154 errMsg = i18n(
"The key(s) you want to encrypt your message "
155 "to are not trusted. No encryption done.");
157 errMsg = i18n(
"The following key(s) are not trusted:\n%1\n"
158 "Their owner(s) will not be able to decrypt the message.")
159 .arg(TQString(aStr));
164 if((index = error.find(
"No encryption keys found for")) != -1)
166 index = error.find(
':',index);
167 int index2 = error.find(
'\n',index);
169 errMsg = i18n(
"Missing encryption key(s) for:\n%1")
170 .arg(TQString(error.mid(index,index2-index)));
174 status |= MISSINGKEY;
180 input =
"- " + input;
181 for (
int idx = 0 ; (idx = input.find(
"\n-", idx)) >= 0 ; idx += 4 )
182 input.replace(idx, 2,
"\n- -");
184 output =
"-----BEGIN PGP SIGNED MESSAGE-----\n\n" + input +
"\n" + output;
187 block.setProcessedText( output );
188 block.setStatus( status );
194 Base5::decrypt( Block& block,
const TQString &passphrase )
199 input = block.text();
200 exitStatus = run(
"pgpv -f +batchmode=1", passphrase);
201 if( !output.isEmpty() )
202 block.setProcessedText( output );
203 block.setError( error );
205 if(exitStatus == -1) {
206 errMsg = i18n(
"Error running PGP");
208 block.setStatus( status );
215 index = error.find(
"Cannot decrypt message");
223 if(error.find(
"Need a pass phrase") != -1)
225 if (!passphrase.isEmpty())
227 errMsg = i18n(
"Bad passphrase; could not decrypt.");
228 kdDebug(5100) <<
"Base: passphrase is bad" << endl;
236 status |= NO_SEC_KEY;
238 errMsg = i18n(
"You do not have the secret key needed to decrypt this message.");
239 kdDebug(5100) <<
"Base: no secret key for this message" << endl;
245 index = error.find(
"can only be decrypted by:");
248 index = error.find(
'\n',index);
249 int end = error.find(
"\n\n",index);
253 while( (index2 = error.find(
'\n',index+1)) <= end )
255 TQCString item = error.mid(index+1,index2-index-1);
256 item.stripWhiteSpace();
257 mRecipients.append(item);
263 index = error.find(
"Good signature");
271 index = error.find(
"Key ID ", index) + 7;
272 block.setSignatureKeyId( error.mid(index, 8) );
275 index = error.find(
'"',index) + 1;
276 int index2 = error.find(
'"', index);
277 block.setSignatureUserId( error.mid(index, index2-index) );
280 block.setSignatureDate(
"" );
282 index = error.find(
"BAD signature");
290 index = error.find(
"Key ID ", index) + 7;
291 block.setSignatureKeyId( error.mid(index, 8) );
294 index = error.find(
'"',index) + 1;
295 int index2 = error.find(
'"', index);
296 block.setSignatureUserId( error.mid(index, index2-index) );
299 block.setSignatureDate(
"" );
301 index = error.find(
"Signature by unknown key");
304 index = error.find(
"keyid: 0x",index) + 9;
305 block.setSignatureKeyId( error.mid(index, 8) );
306 block.setSignatureUserId( TQString() );
312 block.setSignatureDate(
"" );
316 block.setStatus( status );
322 Base5::readPublicKey(
const KeyID& keyId,
const bool readTrust, Key* key )
327 exitStatus = run(
"pgpk -ll 0x" + keyId, 0,
true );
329 if(exitStatus != 0) {
334 key = parseSingleKey( output, key );
343 exitStatus = run(
"pgpk -c 0x" + keyId, 0,
true );
345 if(exitStatus != 0) {
350 parseTrustDataForKey( key, output );
358 Base5::publicKeys(
const TQStringList & patterns )
362 TQCString cmd =
"pgpk -ll";
363 for ( TQStringList::ConstIterator it = patterns.begin();
364 it != patterns.end(); ++it ) {
366 cmd += TDEProcess::quote( *it ).local8Bit();
369 exitStatus = run( cmd, 0,
true );
371 if(exitStatus != 0) {
377 KeyList keys = parseKeyList( output,
false );
387 Base5::secretKeys(
const TQStringList & patterns )
392 TQCString cmd =
"pgpk -ll";
393 for ( TQStringList::ConstIterator it = patterns.begin();
394 it != patterns.end(); ++it ) {
396 cmd += TDEProcess::quote( *it ).local8Bit();
399 exitStatus = run( cmd, 0,
true );
401 if(exitStatus != 0) {
407 KeyList keys = parseKeyList( output,
true );
416 TQCString Base5::getAsciiPublicKey(
const KeyID& keyID)
424 exitStatus = run(
"pgpk -xa 0x" + keyID, 0,
true );
426 if(exitStatus != 0) {
436 Base5::signKey(
const KeyID& keyID,
const TQString &passphrase)
441 if (passphrase.isEmpty())
return false;
443 cmd =
"pgpk -s -f +batchmode=1 0x";
448 exitStatus = run(cmd.data(), passphrase);
459 Base5::parseKeyData(
const TQCString& output,
int& offset, Key* key )
466 if( ( strncmp( output.data() + offset,
"pub", 3 ) != 0 ) &&
467 ( strncmp( output.data() + offset,
"sec", 3 ) != 0 ) )
469 kdDebug(5100) <<
"Unknown key type or corrupt key data.\n";
479 bool primaryKey =
true;
486 eol = output.find(
'\n', offset );
487 if( ( eol == -1 ) || ( eol == offset ) )
492 if( !strncmp( output.data() + offset,
"pub", 3 ) ||
493 !strncmp( output.data() + offset,
"sec", 3 ) ||
494 !strncmp( output.data() + offset,
"sub", 3 ) )
499 subkey =
new Subkey(
"",
false );
500 key->addSubkey( subkey );
511 switch( output[offset+3] )
516 subkey->setDisabled(
true );
517 key->setDisabled(
true );
526 while( output[pos] ==
' ' )
528 pos2 = output.find(
' ', pos );
529 subkey->setKeyLength( output.mid( pos, pos2-pos ).toUInt() );
534 while( output[pos] ==
' ' )
537 pos2 = output.find(
' ', pos );
538 subkey->setKeyID( output.mid( pos, pos2-pos ) );
543 while( output[pos] ==
' ' )
545 pos2 = output.find(
' ', pos );
546 int year = output.mid( pos, 4 ).toInt();
547 int month = output.mid( pos+5, 2 ).toInt();
548 int day = output.mid( pos+8, 2 ).toInt();
549 TQDateTime dt( TQDate( year, month, day ), TQTime( 00, 00 ) );
550 TQDateTime epoch( TQDate( 1970, 01, 01 ), TQTime( 00, 00 ) );
555 subkey->setCreationDate( epoch.secsTo( dt ) );
559 if( primaryKey || !key->revoked() )
562 while( output[pos] ==
' ' )
564 pos2 = output.find(
' ', pos );
565 if( output[pos] ==
'-' )
567 subkey->setExpirationDate( -1 );
569 else if( !strncmp( output.data() + pos,
"*REVOKED*", 9 ) )
571 subkey->setRevoked(
true );
572 key->setRevoked(
true );
576 int year = output.mid( pos, 4 ).toInt();
577 int month = output.mid( pos+5, 2 ).toInt();
578 int day = output.mid( pos+8, 2 ).toInt();
579 TQDateTime dt( TQDate( year, month, day ), TQTime( 00, 00 ) );
580 subkey->setCreationDate( epoch.secsTo( dt ) );
582 if( TQDateTime::currentDateTime() >= dt )
584 subkey->setExpired(
true );
585 key->setExpired(
true );
589 else if( key->revoked() )
590 subkey->setRevoked(
true );
596 while( output[pos] ==
' ' )
598 pos2 = output.find(
' ', pos );
599 if( !strncmp( output.data() + pos,
"RSA", 3 ) )
604 else if( !strncmp( output.data() + pos,
"DSS", 3 ) )
606 else if( !strncmp( output.data() + pos,
"Diffie-Hellman", 14 ) )
609 kdDebug(5100)<<
"Unknown key algorithm\n";
612 subkey->setCanEncrypt( encr );
613 subkey->setCanSign( sign );
614 subkey->setCanCertify( sign );
619 bool canSign =
false;
620 bool canEncr =
false;
622 while( output[pos] ==
' ' )
625 if( !strncmp( output.data() + pos,
"Sign & Encrypt", 14 ) )
630 else if( !strncmp( output.data() + pos,
"Sign only", 9 ) )
632 else if( !strncmp( output.data() + pos,
"Encrypt only", 12 ) )
635 kdDebug(5100)<<
"Unknown key capability\n";
638 if( !key->expired() && !key->revoked() )
640 key->setCanEncrypt( canEncr );
641 key->setCanSign( canSign );
642 key->setCanCertify( canSign );
648 else if( !strncmp( output.data() + offset,
"f16", 3 ) ||
649 !strncmp( output.data() + offset,
"f20", 3 ) )
656 int pos = output.find(
'=', offset+3 ) + 2;
657 TQCString fingerprint = output.mid( pos, eol-pos );
659 for (
int idx = 0 ; (idx = fingerprint.find(
' ', idx)) >= 0 ; )
660 fingerprint.replace( idx, 1,
"" );
661 assert( subkey != 0 );
662 subkey->setFingerprint( fingerprint );
665 else if( !strncmp( output.data() + offset,
"uid", 3 ) )
668 TQCString uid = output.mid( pos, eol-pos );
669 key->addUserID( uid );
678 else if ( !strncmp( output.data() + offset,
"sig", 3 ) ||
679 !strncmp( output.data() + offset,
"SIG", 3 ) ||
680 !strncmp( output.data() + offset,
"ret", 3 ) )
694 Base5::parseSingleKey(
const TQCString& output, Key* key )
699 if( !strncmp( output.data(),
"Type Bits", 9 ) )
703 offset = output.find(
"\nType Bits" ) + 1;
709 offset = output.find(
'\n', offset ) + 1;
713 key = parseKeyData( output, offset, key );
722 Base5::parseKeyList(
const TQCString& output,
bool onlySecretKeys )
729 if( !strncmp( output.data(),
"Type Bits", 9 ) )
733 offset = output.find(
"\nType Bits" ) + 1;
739 offset = output.find(
'\n', offset ) + 1;
745 key = parseKeyData( output, offset );
749 if( !onlySecretKeys || !key->secret() )
764 Base5::parseTrustDataForKey( Key* key,
const TQCString& str )
766 if( ( key == 0 ) || str.isEmpty() )
769 TQCString keyID =
"0x" + key->primaryKeyID();
770 UserIDList userIDs = key->userIDs();
773 int offset = str.find(
"\n\n KeyID" ) + 9;
774 if( offset == -1 + 9 )
777 offset = str.find(
'\n', offset ) + 1;
778 if( offset == -1 + 1 )
781 bool ultimateTrust =
false;
782 if( !strncmp( str.data() + offset+13,
"ultimate", 8 ) )
783 ultimateTrust =
true;
791 if( ( eol = str.find(
'\n', offset ) ) == -1 )
794 if( str[offset+23] !=
' ' )
798 Validity validity = KPGP_VALIDITY_UNKNOWN;
799 if( !strncmp( str.data() + offset+23,
"complete", 8 ) )
801 validity = KPGP_VALIDITY_ULTIMATE;
803 validity = KPGP_VALIDITY_FULL;
804 else if( !strncmp( str.data() + offset+23,
"marginal", 8 ) )
805 validity = KPGP_VALIDITY_MARGINAL;
806 else if( !strncmp( str.data() + offset+23,
"invalid", 7 ) )
807 validity = KPGP_VALIDITY_UNDEFINED;
810 int pos = offset + 33;
811 TQString uid = str.mid( pos, eol-pos );
814 for( UserIDListIterator it( userIDs ); it.current(); ++it )
815 if( (*it)->text() == uid )
817 kdDebug(5100)<<
"Setting the validity of "<<uid<<
" to "<<validity<<endl;
818 (*it)->setValidity( validity );