29#include <tqdatetime.h> 
   32#include <tdeprocess.h> 
   51Base2::encrypt( Block& block, 
const KeyIDList& recipients )
 
   53  return encsign( block, recipients, 0 );
 
   58Base2::clearsign( Block& block, 
const TQString &passphrase )
 
   60  return encsign( block, KeyIDList(), passphrase );
 
   65Base2::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 );
 
  227Base2::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 );
 
  466Base2::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 );
 
  506Base2::publicKeys( 
const TQStringList & patterns )
 
  508  return doGetPublicKeys( PGP2 
" +batchmode +language=en +verbose=0 -kvc -f",
 
  513Base2::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() );
 
  569Base2::secretKeys( 
const TQStringList & patterns )
 
  571  return publicKeys( patterns );
 
  576Base2::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);
 
  595TQCString Base2::getAsciiPublicKey(
const KeyID& keyID)
 
  603  exitStatus = run( PGP2 
" +batchmode +force +language=en -kxaf 0x" + keyID,
 
  606  if(exitStatus != 0) {
 
  616Base2::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 ) );
 
  821Base2::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 );
 
  896Base2::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 ) );