Chiasmus: body decryption implemented (without using QCString, to avoid data copying just

to null-terminate it; and for easier Qt4 porting one day :).

svn path=/branches/kdepim/proko2/kdepim/; revision=415365
wilder-work
David Faure 21 years ago
parent 47b1e47aff
commit 397bb7f676
  1. 15
      bodypartformatter.cpp
  2. 231
      objecttreeparser.cpp
  3. 8
      objecttreeparser.h

@ -111,6 +111,9 @@ namespace {
CREATE_BODY_PART_FORMATTER(ApplicationOctetStream)
CREATE_BODY_PART_FORMATTER(ApplicationPkcs7Mime)
#ifdef KLEO_CHIASMUS
CREATE_BODY_PART_FORMATTER(ApplicationChiasmusText)
#endif
//CREATE_BODY_PART_FORMATTER(ApplicationPgp)
CREATE_BODY_PART_FORMATTER(MessageRfc822)
@ -143,7 +146,10 @@ static const SubtypeBuiltin applicationSubtypeBuiltins[] = {
{ "octet-stream", &ApplicationOctetStreamBodyPartFormatter::create },
{ "pkcs7-mime", &ApplicationPkcs7MimeBodyPartFormatter::create },
{ "x-pkcs7-mime", &ApplicationPkcs7MimeBodyPartFormatter::create },
{ "pgp", &ApplicationPgpBodyPartFormatter::create },
#ifdef KLEO_CHIASMUS
{ "vnd.de.bund.bsi.chiasmus-text", &ApplicationChiasmusTextBodyPartFormatter::create },
#endif
{ "pgp", &ApplicationPgpBodyPartFormatter::create }
};
static const SubtypeBuiltin textSubtypeBuiltins[] = {
@ -286,6 +292,13 @@ static const KMail::BodyPartFormatter * createForApplication( const char * subty
//if ( qstricmp( subtype, "ms-tnef" ) == 0 )
// return ApplicationMsTnefBodyPartFormatter::create();
break;
#ifdef KLEO_CHIASMUS
case 'v':
case 'V':
if ( qstricmp( subtype, "vnd.de.bund.bsi.chiasmus-text") == 0)
return ApplicationChiasmusTextBodyPartFormatter::create();
break;
#endif
}
return AnyTypeBodyPartFormatter::create();

@ -60,6 +60,12 @@
#include <mimelib/string.h>
#include <mimelib/text.h>
#ifdef KLEO_CHIASMUS
#include <kleo/specialjob.h>
#include <kleo/cryptobackend.h>
#include <kleo/cryptobackendfactory.h>
#endif
#include <gpgmepp/importresult.h>
#include <kpgpblock.h>
@ -74,6 +80,7 @@
#include <ktempfile.h>
#include <kstandarddirs.h>
#include <kapplication.h>
#include <kinputdialog.h>
#include <kmessagebox.h>
// other Qt headers
@ -978,9 +985,10 @@ namespace KMail {
// process old style not-multipart Mailman messages to
// enable verification of the embedded messages' signatures
if ( !isMailmanMessage( curNode ) ||
!processMailmanMessage( curNode ) )
writeBodyString( cstr, curNode->trueFromAddress(),
codecFor( curNode ), result );
!processMailmanMessage( curNode ) ) {
writeBodyString( cstr, curNode->trueFromAddress(),
codecFor( curNode ), result );
}
if ( bDrawFrame )
htmlWriter()->queue( "</td></tr></table>" );
@ -1273,7 +1281,7 @@ namespace KMail {
}
bool ObjectTreeParser::processApplicationOctetStreamSubtype( partNode * node, ProcessResult & result ) {
bool ObjectTreeParser::processApplicationOctetStreamSubtype( partNode * node, ProcessResult & result ) {
if ( partNode * child = node->firstChild() ) {
kdDebug(5006) << "\n-----> Calling parseObjectTree( curNode->mChild )\n" << endl;
ObjectTreeParser otp( mReader, cryptPlugWrapper() );
@ -1354,9 +1362,9 @@ namespace KMail {
}
setCryptPlugWrapper( oldUseThisCryptPlug );
return false;
}
}
bool ObjectTreeParser::processApplicationPkcs7MimeSubtype( partNode * node, ProcessResult & result ) {
bool ObjectTreeParser::processApplicationPkcs7MimeSubtype( partNode * node, ProcessResult & result ) {
if ( partNode * child = node->firstChild() ) {
kdDebug(5006) << "\n-----> Calling parseObjectTree( curNode->mChild )\n" << endl;
ObjectTreeParser otp( mReader, cryptPlugWrapper() );
@ -1556,70 +1564,181 @@ namespace KMail {
}
return isSigned || isEncrypted;
}
#ifdef KLEO_CHIASMUS
bool ObjectTreeParser::decryptChiasmus( const QByteArray& data, QByteArray& bodyDecoded, QString& errorText )
{
const Kleo::CryptoBackend::Protocol * chiasmus =
Kleo::CryptoBackendFactory::instance()->protocol( "Chiasmus" );
Q_ASSERT( chiasmus );
if ( !chiasmus )
return false;
const std::auto_ptr<Kleo::SpecialJob> listjob( chiasmus->specialJob( "x-obtain-keys", QMap<QString,QVariant>() ) );
if ( !listjob.get() ) {
errorText = i18n( "Chiasmus backend does not offer the "
"\"x-obtain-keys\" function. Please report this bug." );
return false;
}
void ObjectTreeParser::writeBodyString( const QCString & bodyString,
const QString & fromAddress,
const QTextCodec * codec,
ProcessResult & result ) {
assert( mReader ); assert( codec );
KMMsgSignatureState inlineSignatureState = result.inlineSignatureState();
KMMsgEncryptionState inlineEncryptionState = result.inlineEncryptionState();
writeBodyStr( bodyString, codec, fromAddress,
inlineSignatureState, inlineEncryptionState );
result.setInlineSignatureState( inlineSignatureState );
result.setInlineEncryptionState( inlineEncryptionState );
if ( listjob->exec() ) {
errorText = i18n( "Chiasmus Backend Error" );
return false;
}
void ObjectTreeParser::writePartIcon( KMMessagePart * msgPart, int partNum, bool inlineImage ) {
if ( !mReader || !msgPart )
return;
const QVariant result = listjob->property( "result" );
if ( result.type() != QVariant::StringList ) {
errorText = i18n( "Unexpected return value from Chiasmus backend: "
"The \"x-obtain-keys\" function did not return a "
"string list. Please report this bug." );
return false;
}
kdDebug(5006) << "writePartIcon: PartNum: " << partNum << endl;
const QStringList keys = result.toStringList();
if ( keys.empty() ) {
errorText = i18n( "No keys have been found. Please check that a "
"valid key path has been set in the Chiasmus "
"configuration." );
return false;
}
QString label = msgPart->fileName();
if( label.isEmpty() )
label = msgPart->name();
if( label.isEmpty() )
label = "unnamed";
label = KMMessage::quoteHtmlChars( label, true );
bool ok = false;
const QString key = KInputDialog::getItem( i18n( "Chiasmus Decryption Key Selection" ),
i18n( "Please select the Chiasmus key file to use:" ),
keys, 0, false, &ok, mReader );
if ( !ok )
return false;
QString comment = msgPart->contentDescription();
comment = KMMessage::quoteHtmlChars( comment, true );
assert( !key.isEmpty() );
QString fileName = mReader->writeMessagePartToTempFile( msgPart, partNum );
Kleo::SpecialJob * job = chiasmus->specialJob( "x-decrypt", QMap<QString,QVariant>() );
if ( !job ) {
errorText = i18n( "Chiasmus backend does not offer the "
"\"x-decrypt\" function. Please report this bug." );
return false;
}
QString href = fileName.isEmpty() ?
"part://" + QString::number( partNum + 1 ) :
"file:" + KURL::encode_string( fileName ) ;
if ( !job->setProperty( "key", key ) ||
!job->setProperty( "input", data ) ) {
errorText = i18n( "The \"x-decrypt\" function does no accept "
"\"key\" or \"input\" parameters. Please report this bug." );
return false;
}
QString iconName;
if( inlineImage )
iconName = href;
else {
if ( job->exec() ) {
errorText = i18n( "Chiasmus Decryption Error" );
return false;
}
const QVariant resultData = job->property( "result" );
if ( resultData.type() != QVariant::ByteArray ) {
errorText = i18n( "Unexpected return value from Chiasmus backend: "
"The \"x-decrypt\" function did not return a "
"byte array. Please report this bug." );
return false;
}
bodyDecoded = resultData.toByteArray();
return true;
}
bool ObjectTreeParser::processApplicationChiasmusTextSubtype( partNode * curNode, ProcessResult & result )
{
if ( !mReader ) {
mRawReplyString = curNode->msgPart().bodyDecoded();
mTextualContent += curNode->msgPart().bodyToUnicode();
mTextualContentCharset = curNode->msgPart().charset();
return true;
}
QByteArray decryptedBody;
QString errorText;
const QByteArray data = curNode->msgPart().bodyDecodedBinary();
bool bOkDecrypt = decryptChiasmus( data, decryptedBody, errorText );
PartMetaData messagePart;
messagePart.isDecryptable = bOkDecrypt;
messagePart.isEncrypted = true;
messagePart.isSigned = false;
messagePart.errorText = errorText;
if ( mReader )
htmlWriter()->queue( writeSigstatHeader( messagePart,
0, //cryptPlugWrapper(),
curNode->trueFromAddress() ) );
const QByteArray body = bOkDecrypt ? decryptedBody : data;
const QString chiasmusCharset = curNode->contentTypeParameter("chiasmus-charset");
const QTextCodec* aCodec = chiasmusCharset.isEmpty()
? codecFor( curNode )
: KMMsgBase::codecForName( chiasmusCharset.ascii() );
htmlWriter()->queue( quotedHTML( aCodec->toUnicode( body ) ) );
result.setInlineEncryptionState( KMMsgFullyEncrypted );
if ( mReader )
htmlWriter()->queue( writeSigstatFooter( messagePart ) );
return true;
}
#endif
void ObjectTreeParser::writeBodyString( const QCString & bodyString,
const QString & fromAddress,
const QTextCodec * codec,
ProcessResult & result ) {
assert( mReader ); assert( codec );
KMMsgSignatureState inlineSignatureState = result.inlineSignatureState();
KMMsgEncryptionState inlineEncryptionState = result.inlineEncryptionState();
writeBodyStr( bodyString, codec, fromAddress,
inlineSignatureState, inlineEncryptionState );
result.setInlineSignatureState( inlineSignatureState );
result.setInlineEncryptionState( inlineEncryptionState );
}
void ObjectTreeParser::writePartIcon( KMMessagePart * msgPart, int partNum, bool inlineImage ) {
if ( !mReader || !msgPart )
return;
kdDebug(5006) << "writePartIcon: PartNum: " << partNum << endl;
QString label = msgPart->fileName();
if( label.isEmpty() )
label = msgPart->name();
if( label.isEmpty() )
label = "unnamed";
label = KMMessage::quoteHtmlChars( label, true );
QString comment = msgPart->contentDescription();
comment = KMMessage::quoteHtmlChars( comment, true );
QString fileName = mReader->writeMessagePartToTempFile( msgPart, partNum );
QString href = fileName.isEmpty() ?
"part://" + QString::number( partNum + 1 ) :
"file:" + KURL::encode_string( fileName ) ;
QString iconName;
if( inlineImage )
iconName = href;
else {
iconName = msgPart->iconName();
if( iconName.right( 14 ) == "mime_empty.png" ) {
msgPart->magicSetType();
iconName = msgPart->iconName();
if( iconName.right( 14 ) == "mime_empty.png" ) {
msgPart->magicSetType();
iconName = msgPart->iconName();
}
}
if( inlineImage )
// show the filename of the image below the embedded image
htmlWriter()->queue( "<div><a href=\"" + href + "\">"
"<img src=\"" + iconName + "\" border=\"0\"></a>"
"</div>"
"<div><a href=\"" + href + "\">" + label + "</a>"
"</div>"
"<div>" + comment + "</div><br>" );
else
// show the filename next to the image
htmlWriter()->queue( "<div><a href=\"" + href + "\"><img src=\"" +
iconName + "\" border=\"0\">" + label +
"</a></div>"
"<div>" + comment + "</div><br>" );
}
if( inlineImage )
// show the filename of the image below the embedded image
htmlWriter()->queue( "<div><a href=\"" + href + "\">"
"<img src=\"" + iconName + "\" border=\"0\"></a>"
"</div>"
"<div><a href=\"" + href + "\">" + label + "</a>"
"</div>"
"<div>" + comment + "</div><br>" );
else
// show the filename next to the image
htmlWriter()->queue( "<div><a href=\"" + href + "\"><img src=\"" +
iconName + "\" border=\"0\">" + label +
"</a></div>"
"<div>" + comment + "</div><br>" );
}
#define SIG_FRAME_COL_UNDEF 99
#define SIG_FRAME_COL_RED -1
#define SIG_FRAME_COL_YELLOW 0

@ -201,7 +201,7 @@ namespace KMail {
bool processMailmanMessage( partNode * node );
public:// (during refactoring)
public:// for BodyPartFormatter (during refactoring)
bool processTextHtmlSubtype( partNode * node, ProcessResult & result );
bool processTextPlainSubtype( partNode * node, ProcessResult & result );
@ -217,8 +217,14 @@ namespace KMail {
bool processApplicationOctetStreamSubtype( partNode * node, ProcessResult & result );
bool processApplicationPkcs7MimeSubtype( partNode * node, ProcessResult & result );
#ifdef KLEO_CHIASMUS
bool processApplicationChiasmusTextSubtype( partNode * node, ProcessResult & result );
#endif
private:
#ifdef KLEO_CHIASMUS
bool decryptChiasmus( const QByteArray& data, QByteArray& bodyDecoded, QString& errorText );
#endif
void writeBodyString( const QCString & bodyString,
const QString & fromAddress,
const QTextCodec * codec,

Loading…
Cancel
Save