29 #include <tqdatetime.h>
31 #include <tdelocale.h>
32 #include <tdeprocess.h>
51 Base2::encrypt( Block& block,
const KeyIDList& recipients )
53 return encsign( block, recipients, 0 );
58 Base2::clearsign( Block& block,
const TQString &passphrase )
60 return encsign( block, KeyIDList(), passphrase );
65 Base2::encsign( Block& block,
const KeyIDList& recipients,
66 const TQString &passphrase )
71 if (!recipients.isEmpty() && !passphrase.isEmpty())
72 cmd = PGP2
" +batchmode +language=en +verbose=1 -seat";
73 else if(!recipients.isEmpty())
74 cmd = PGP2
" +batchmode +language=en +verbose=1 -eat";
75 else if (!passphrase.isEmpty())
76 cmd = PGP2
" +batchmode +language=en +verbose=1 -sat";
79 kdDebug(5100) <<
"kpgpbase: Neither recipients nor passphrase specified." << endl;
83 if (!passphrase.isEmpty())
86 if(!recipients.isEmpty()) {
87 if(Module::getKpgp()->encryptToSelf())
90 cmd += Module::getKpgp()->user();
93 for( KeyIDList::ConstIterator it = recipients.begin();
94 it != recipients.end(); ++it ) {
102 input = block.text();
103 exitStatus = run(cmd.data(), passphrase);
104 if( !output.isEmpty() )
105 block.setProcessedText( output );
106 block.setError( error );
115 if(!recipients.isEmpty())
119 unsigned int num = 0;
120 TQCString badkeys =
"";
121 if (error.find(
"Cannot find the public key") != -1)
125 while((index = error.find(
"Cannot find the public key",index))
129 index = error.find(
'\'',index);
130 int index2 = error.find(
'\'',index+1);
133 badkeys += error.mid(index, index2-index+1);
137 badkeys.stripWhiteSpace();
138 if(num == recipients.count())
139 errMsg = i18n(
"Could not find public keys matching the userid(s)\n"
141 "the message is not encrypted.")
142 .arg( badkeys.data() );
144 errMsg = i18n(
"Could not find public keys matching the userid(s)\n"
146 "these persons will not be able to read the message.")
147 .arg( badkeys.data() );
148 status |= MISSINGKEY;
152 if (error.find(
"skipping userid") != -1)
156 while((index = error.find(
"skipping userid",index))
160 int index2 = error.find(
'\n',index+16);
163 badkeys += error.mid(index+16, index2-index-16);
168 badkeys.stripWhiteSpace();
169 if(num == recipients.count())
170 errMsg = i18n(
"Public keys not certified with trusted signature "
173 "The message is not encrypted.")
174 .arg( badkeys.data() );
176 errMsg = i18n(
"Public keys not certified with trusted signature "
179 "these persons will not be able to read the message.")
180 .arg( badkeys.data() );
188 if (!passphrase.isEmpty())
190 if(error.find(
"Pass phrase is good") != -1)
195 if( error.find(
"Bad pass phrase") != -1)
197 errMsg = i18n(
"Bad passphrase; could not sign.");
199 status |= ERR_SIGNING;
203 if (error.find(
"Signature error") != -1)
205 errMsg = i18n(
"Signing failed: please check your PGP User Identity, "
206 "the PGP setup, and the key rings.");
207 status |= NO_SEC_KEY;
208 status |= ERR_SIGNING;
211 if (error.find(
"Encryption error") != -1)
213 errMsg = i18n(
"Encryption failed: please check your PGP setup "
214 "and the key rings.");
215 status |= NO_SEC_KEY;
221 block.setStatus( status );
227 Base2::decrypt( Block& block,
const TQString &passphrase )
233 input = block.text();
234 exitStatus = run(PGP2
" +batchmode +language=en -f", passphrase);
235 if( !output.isEmpty() )
236 block.setProcessedText( output );
237 block.setError( error );
241 if(error.find(
"ASCII armor corrupted.") != -1)
243 kdDebug(5100) <<
"removing ASCII armor header" << endl;
244 int index1 = input.find(
"-----BEGIN PGP SIGNED MESSAGE-----");
246 index1 = input.find(
"-----BEGIN PGP SIGNATURE-----", index1);
248 index1 = input.find(
"-----BEGIN PGP MESSAGE-----");
249 index1 = input.find(
'\n', index1);
250 index2 = input.find(
"\n\n", index1);
251 input.remove(index1, index2 - index1);
252 exitStatus = run(PGP2
" +batchmode +language=en -f", passphrase);
253 if( !output.isEmpty() )
254 block.setProcessedText( output );
255 block.setError( error );
258 if(exitStatus == -1) {
259 errMsg = i18n(
"error running PGP");
261 block.setStatus( status );
285 if(error.find(
"File is encrypted.") != -1)
289 if((index = error.find(
"Key for user ID:")) != -1)
293 index2 = error.find(
'\n', index);
294 block.setRequiredUserId( error.mid(index, index2 - index) );
297 if ((!passphrase.isEmpty()) && (error.find(
"Bad pass phrase") != -1))
299 errMsg = i18n(
"Bad passphrase; could not decrypt.");
300 kdDebug(5100) <<
"Base: passphrase is bad" << endl;
308 status |= NO_SEC_KEY;
310 errMsg = i18n(
"You do not have the secret key needed to decrypt this message.");
311 kdDebug(5100) <<
"Base: no secret key for this message" << endl;
317 index = error.find(
"can only be read by:");
320 index = error.find(
'\n',index);
321 int end = error.find(
"\n\n",index);
324 while( (index2 = error.find(
'\n',index+1)) <= end )
326 TQCString item = error.mid(index+1,index2-index-1);
327 item.stripWhiteSpace();
328 mRecipients.append(item);
395 if((index = error.find(
"File has signature")) != -1)
398 index = error.find(
'\n', index+18) + 1;
402 if ((index2 = error.find(
"Signature made", index)) != -1) {
404 int index3 = error.find(
"using", index2);
405 block.setSignatureDate( error.mid(index2, index3-index2-1) );
406 kdDebug(5100) <<
"Message was signed on '" << block.signatureDate() <<
"'\n";
407 index3 = error.find(
"key ID ", index3) + 7;
408 block.setSignatureKeyId( error.mid(index3,8) );
409 kdDebug(5100) <<
"Message was signed with key '" << block.signatureKeyId() <<
"'\n";
414 block.setSignatureDate(
"" );
415 block.setSignatureKeyId(
"" );
418 if( ( index2 = error.find(
"Key matching expected", index) ) != -1)
420 status |= UNKNOWN_SIG;
422 int index3 = error.find(
"Key ID ", index2) + 7;
423 block.setSignatureKeyId( error.mid(index3,8) );
424 block.setSignatureUserId( TQString() );
426 else if( (index2 = error.find(
"Good signature from", index)) != -1 )
430 index = error.find(
'"',index2+19);
431 index2 = error.find(
'"', index+1);
432 block.setSignatureUserId( error.mid(index+1, index2-index-1) );
434 else if( (index2 = error.find(
"Bad signature from", index)) != -1 )
438 index = error.find(
'"',index2+19);
439 index2 = error.find(
'"', index+1);
440 block.setSignatureUserId( error.mid(index+1, index2-index-1) );
442 else if( error.find(
"Keyring file", index) != -1 )
445 status |= UNKNOWN_SIG;
448 index = error.find(
'\'', index) + 1;
449 index2 = error.find(
'\'', index);
450 block.setSignatureUserId( i18n(
"The keyring file %1 does not exist.\n"
451 "Please check your PGP setup.").arg(TQString(error.mid(index, index2-index))) );
456 block.setSignatureUserId( i18n(
"Unknown error") );
460 block.setStatus( status );
466 Base2::readPublicKey(
const KeyID& keyID,
467 const bool readTrust ,
473 exitStatus = run( PGP2
" +batchmode +language=en +verbose=0 -kvc -f 0x" +
476 if(exitStatus != 0) {
481 key = parsePublicKeyData( output, key );
490 exitStatus = run( PGP2
" +batchmode +language=en +verbose=0 -kc -f",
493 if(exitStatus != 0) {
498 parseTrustDataForKey( key, error );
506 Base2::publicKeys(
const TQStringList & patterns )
508 return doGetPublicKeys( PGP2
" +batchmode +language=en +verbose=0 -kvc -f",
513 Base2::doGetPublicKeys(
const TQCString & cmd,
const TQStringList & patterns )
519 if ( patterns.isEmpty() ) {
520 exitStatus = run( cmd, 0,
true );
522 if ( exitStatus != 0 ) {
528 publicKeys = parseKeyList( output,
false );
531 typedef TQMap<TQCString, Key*> KeyMap;
534 for ( TQStringList::ConstIterator it = patterns.begin();
535 it != patterns.end(); ++it ) {
536 exitStatus = run( cmd +
" " + TDEProcess::quote( *it ).local8Bit(),
539 if ( exitStatus != 0 ) {
545 publicKeys = parseKeyList( output,
false );
548 while ( !publicKeys.isEmpty() ) {
549 Key * key = publicKeys.take( 0 );
550 if ( !map.contains( key->primaryFingerprint() ) )
551 map.insert( key->primaryFingerprint(), key );
557 for ( KeyMap::ConstIterator it = map.begin(); it != map.end(); ++it ) {
558 publicKeys.append( it.data() );
569 Base2::secretKeys(
const TQStringList & patterns )
571 return publicKeys( patterns );
576 Base2::signKey(
const KeyID& keyID,
const TQString &passphrase)
581 cmd = PGP2
" +batchmode +language=en -ks -f ";
583 cmd +=
" 0x" + keyID;
586 exitStatus = run(cmd.data(),passphrase);
595 TQCString Base2::getAsciiPublicKey(
const KeyID& keyID)
603 exitStatus = run( PGP2
" +batchmode +force +language=en -kxaf 0x" + keyID,
606 if(exitStatus != 0) {
616 Base2::parsePublicKeyData(
const TQCString& output, Key* key )
622 if( !strncmp( output.data(),
"pub", 3 ) ||
623 !strncmp( output.data(),
"sec", 3 ) )
632 index = output.find(
"\npub" );
644 if( ( index2 = output.find(
'\n', index ) ) == -1 )
647 if( !strncmp( output.data() + index,
"pub", 3 ) ||
648 !strncmp( output.data() + index,
"sec", 3 ) )
667 key->setCanEncrypt(
true );
668 key->setCanSign(
true );
669 key->setCanCertify(
true );
672 subkey =
new Subkey(
"",
false );
673 key->addSubkey( subkey );
675 subkey->setCanEncrypt(
true );
676 subkey->setCanSign(
true );
677 subkey->setCanCertify(
true );
679 subkey->setExpirationDate( -1 );
682 switch( output[index+3] )
687 subkey->setDisabled(
true );
688 key->setDisabled(
true );
691 subkey->setExpired(
true );
692 key->setExpired(
true );
695 kdDebug(5100) <<
"Unknown key flag.\n";
700 while( output[pos] ==
' ' )
702 pos2 = output.find(
'/', pos );
703 subkey->setKeyLength( output.mid( pos, pos2-pos ).toUInt() );
707 pos2 = output.find(
' ', pos );
708 subkey->setKeyID( output.mid( pos, pos2-pos ) );
712 while( output[pos] ==
' ' )
714 pos2 = output.find(
' ', pos );
715 int year = output.mid( pos, 4 ).toInt();
716 int month = output.mid( pos+5, 2 ).toInt();
717 int day = output.mid( pos+8, 2 ).toInt();
718 TQDateTime dt( TQDate( year, month, day ), TQTime( 00, 00 ) );
719 TQDateTime epoch( TQDate( 1970, 01, 01 ), TQTime( 00, 00 ) );
724 subkey->setCreationDate( epoch.secsTo( dt ) );
728 while( output[pos] ==
' ' )
730 TQCString uid = output.mid( pos, index2-pos );
731 if( uid !=
"*** KEY REVOKED ***" )
732 key->addUserID( uid );
735 subkey->setRevoked(
true );
736 key->setRevoked(
true );
739 else if( output[index] ==
' ' )
744 assert( subkey != 0 );
747 while( output[pos] ==
' ' )
750 if( !strncmp( output.data() + pos,
"Key fingerprint = ", 18 ) )
755 TQCString fingerprint = output.mid( pos, index2-pos );
757 for (
int idx = 0 ; (idx = fingerprint.find(
' ', idx)) >= 0 ; )
758 fingerprint.replace( idx, 1,
"" );
760 subkey->setFingerprint( fingerprint );
762 else if( !strncmp( output.data() + pos,
"Expire: ", 8 ) ||
763 !strncmp( output.data() + pos,
"no expire ", 10 ) )
770 if( output[pos] ==
'E' )
774 int year = output.mid( pos, 4 ).toInt();
775 int month = output.mid( pos+5, 2 ).toInt();
776 int day = output.mid( pos+8, 2 ).toInt();
777 TQDateTime dt( TQDate( year, month, day ), TQTime( 00, 00 ) );
778 TQDateTime epoch( TQDate( 1970, 01, 01 ), TQTime( 00, 00 ) );
780 subkey->setExpirationDate( epoch.secsTo( dt ) );
789 if( !strncmp( output.data() + pos,
"SIGNature only", 14 ) )
791 subkey->setCanEncrypt(
false );
792 key->setCanEncrypt(
false );
794 else if( !strncmp( output.data() + pos,
"ENCRyption only", 15 ) )
796 subkey->setCanSign(
false );
797 key->setCanSign(
false );
798 subkey->setCanCertify(
false );
799 key->setCanCertify(
false );
808 key->addUserID( output.mid( pos, index2-pos ) );
821 Base2::parseTrustDataForKey( Key* key,
const TQCString& str )
823 if( ( key == 0 ) || str.isEmpty() )
826 TQCString keyID = key->primaryKeyID();
827 UserIDList userIDs = key->userIDs();
830 int index = str.find(
'\n' ) + 1;
831 while( ( index > 0 ) &&
832 ( strncmp( str.data() + index+2, keyID.data(), 8 ) != 0 ) )
833 index = str.find(
'\n', index ) + 1;
838 bool ultimateTrust =
false;
839 if( !strncmp( str.data() + index+11,
"ultimate", 8 ) )
840 ultimateTrust =
true;
842 bool firstLine =
true;
849 if( ( index2 = str.find(
'\n', index ) ) == -1 )
853 if( !firstLine && ( str[index+2] !=
' ' ) )
856 if( str[index+21] !=
' ' )
860 Validity validity = KPGP_VALIDITY_UNKNOWN;
861 if( !strncmp( str.data() + index+21,
"complete", 8 ) )
863 validity = KPGP_VALIDITY_ULTIMATE;
865 validity = KPGP_VALIDITY_FULL;
866 else if( !strncmp( str.data() + index+21,
"marginal", 8 ) )
867 validity = KPGP_VALIDITY_MARGINAL;
868 else if( !strncmp( str.data() + index+21,
"never", 5 ) )
869 validity = KPGP_VALIDITY_NEVER;
870 else if( !strncmp( str.data() + index+21,
"undefined", 9 ) )
871 validity = KPGP_VALIDITY_UNDEFINED;
874 int pos = index + 31;
875 if( str[index+2] ==
' ' )
877 TQString uid = str.mid( pos, index2-pos );
880 for( UserIDListIterator it( userIDs ); it.current(); ++it )
881 if( (*it)->text() == uid )
883 kdDebug(5100)<<
"Setting the validity of "<<uid<<
" to "<<validity<<endl;
884 (*it)->setValidity( validity );
896 Base2::parseKeyList(
const TQCString& output,
bool secretKeys )
898 kdDebug(5100) <<
"Kpgp::Base2::parseKeyList()" << endl;
905 if( !strncmp( output.data(),
"pub", 3 ) ||
906 !strncmp( output.data(),
"sec", 3 ) )
911 index = output.find(
"\nsec" );
913 index = output.find(
"\npub" );
925 if( ( index2 = output.find(
'\n', index ) ) == -1 )
928 if( !strncmp( output.data() + index,
"pub", 3 ) ||
929 !strncmp( output.data() + index,
"sec", 3 ) )
946 key->setSecret( secretKeys );
948 key->setCanEncrypt(
true );
949 key->setCanSign(
true );
950 key->setCanCertify(
true );
952 subkey =
new Subkey(
"", secretKeys );
953 key->addSubkey( subkey );
955 subkey->setCanEncrypt(
true );
956 subkey->setCanSign(
true );
957 subkey->setCanCertify(
true );
959 subkey->setExpirationDate( -1 );
962 switch( output[index+3] )
967 subkey->setDisabled(
true );
968 key->setDisabled(
true );
971 subkey->setExpired(
true );
972 key->setExpired(
true );
975 kdDebug(5100) <<
"Unknown key flag.\n";
980 while( output[pos] ==
' ' )
982 pos2 = output.find(
'/', pos );
983 subkey->setKeyLength( output.mid( pos, pos2-pos ).toUInt() );
987 pos2 = output.find(
' ', pos );
988 subkey->setKeyID( output.mid( pos, pos2-pos ) );
992 while( output[pos] ==
' ' )
994 pos2 = output.find(
' ', pos );
995 int year = output.mid( pos, 4 ).toInt();
996 int month = output.mid( pos+5, 2 ).toInt();
997 int day = output.mid( pos+8, 2 ).toInt();
998 TQDateTime dt( TQDate( year, month, day ), TQTime( 00, 00 ) );
999 TQDateTime epoch( TQDate( 1970, 01, 01 ), TQTime( 00, 00 ) );
1004 subkey->setCreationDate( epoch.secsTo( dt ) );
1008 while( output[pos] ==
' ' )
1010 TQCString uid = output.mid( pos, index2-pos );
1011 if( uid !=
"*** KEY REVOKED ***" )
1012 key->addUserID( uid );
1015 subkey->setRevoked(
true );
1016 key->setRevoked(
true );
1019 else if( output[index] ==
' ' )
1025 int pos = index + 1;
1026 while( output[pos] ==
' ' )
1029 if( !strncmp( output.data() + pos,
"Key fingerprint = ", 18 ) )
1036 TQCString fingerprint = output.mid( pos, index2-pos );
1038 for (
int idx = 0 ; (idx = fingerprint.find(
' ', idx)) >= 0 ; )
1039 fingerprint.replace( idx, 1,
"" );
1041 subkey->setFingerprint( fingerprint );
1043 else if( !strncmp( output.data() + pos,
"Expire: ", 8 ) ||
1044 !strncmp( output.data() + pos,
"no expire ", 10 ) )
1051 if( output[pos] ==
'E' )
1055 int year = output.mid( pos, 4 ).toInt();
1056 int month = output.mid( pos+5, 2 ).toInt();
1057 int day = output.mid( pos+8, 2 ).toInt();
1058 TQDateTime dt( TQDate( year, month, day ), TQTime( 00, 00 ) );
1059 TQDateTime epoch( TQDate( 1970, 01, 01 ), TQTime( 00, 00 ) );
1061 subkey->setExpirationDate( epoch.secsTo( dt ) );
1070 if( !strncmp( output.data() + pos,
"SIGNature only", 14 ) )
1072 subkey->setCanEncrypt(
false );
1073 key->setCanEncrypt(
false );
1075 else if( !strncmp( output.data() + pos,
"ENCRyption only", 15 ) )
1077 subkey->setCanSign(
false );
1078 key->setCanSign(
false );
1079 subkey->setCanCertify(
false );
1080 key->setCanCertify(
false );
1089 key->addUserID( output.mid( pos, index2-pos ) );