37 #include "qgpgmejob.h"
38 #include "qgpgmeprogresstokenmapper.h"
41 #include <ui/passphrasedialog.h>
43 #include <qgpgme/eventloopinteractor.h>
44 #include <qgpgme/dataprovider.h>
46 #include <gpgmepp/context.h>
47 #include <gpgmepp/data.h>
49 #include <tdelocale.h>
50 #include <kstandarddirs.h>
53 #include <tqstringlist.h>
62 class InvarianceChecker {
71 _this->checkInvariants();
73 ~InvarianceChecker() {
74 _this->checkInvariants();
82 Kleo::QGpgMEJob::QGpgMEJob(
Kleo::Job * _this, GpgME::Context * context )
83 : GpgME::ProgressProvider(),
84 GpgME::PassphraseProvider(),
88 mInDataDataProvider( 0 ),
90 mOutDataDataProvider( 0 ),
92 mReplacedPattern( 0 ),
95 mPatternStartIndex( 0 ), mPatternEndIndex( 0 )
97 InvarianceChecker check(
this );
99 TQObject::connect( QGpgME::EventLoopInteractor::instance(), TQ_SIGNAL(aboutToDestroy()),
100 _this, TQ_SLOT(slotCancel()) );
101 context->setProgressProvider(
this );
105 if ( context->protocol() == GpgME::Context::OpenPGP )
106 context->setPassphraseProvider(
this );
109 void Kleo::QGpgMEJob::checkInvariants()
const {
112 assert( mPatterns[mNumPatterns] == 0 );
113 if ( mPatternEndIndex > 0 ) {
114 assert( mPatternEndIndex > mPatternStartIndex );
115 assert( mPatternEndIndex - mPatternStartIndex == mChunkSize );
117 assert( mPatternEndIndex == mPatternStartIndex );
119 if ( mPatternEndIndex < mNumPatterns ) {
120 assert( mPatterns[mPatternEndIndex] == 0 );
121 assert( mReplacedPattern != 0 );
123 assert( mReplacedPattern == 0 );
126 assert( mNumPatterns == 0 );
127 assert( mPatternStartIndex == 0 );
128 assert( mPatternEndIndex == 0 );
129 assert( mReplacedPattern == 0 );
134 Kleo::QGpgMEJob::~QGpgMEJob() {
135 InvarianceChecker check(
this );
136 delete mCtx; mCtx = 0;
137 delete mInData; mInData = 0;
138 delete mInDataDataProvider; mInDataDataProvider = 0;
139 delete mOutData; mOutData = 0;
140 delete mOutDataDataProvider; mOutDataDataProvider = 0;
144 void Kleo::QGpgMEJob::deleteAllPatterns() {
146 for (
unsigned int i = 0 ; i < mNumPatterns ; ++i )
147 free( (
void*)mPatterns[i] );
148 free( (
void*)mReplacedPattern ); mReplacedPattern = 0;
149 delete[] mPatterns; mPatterns = 0;
150 mPatternEndIndex = mPatternStartIndex = mNumPatterns = 0;
154 mCtx->setManagedByEventLoopInteractor(
true );
155 TQObject::connect( QGpgME::EventLoopInteractor::instance(),
156 TQ_SIGNAL(operationDoneEventSignal(GpgME::Context*,
const GpgME::Error&)),
157 mThis, TQ_SLOT(slotOperationDoneEvent(GpgME::Context*,
const GpgME::Error&)) );
161 InvarianceChecker check(
this );
164 mPatterns =
new const char*[ sl.size() + 1 ];
165 const char* * pat_it = mPatterns;
167 for ( TQStringList::const_iterator it = sl.begin() ; it != sl.end() ; ++it ) {
168 if ( (*it).isNull() )
170 if ( (*it).isEmpty() && !allowEmpty )
172 *pat_it++ = strdup( (*it).utf8().data() );
176 mReplacedPattern = 0;
177 mPatternEndIndex = mChunkSize = mNumPatterns;
181 InvarianceChecker check(
this );
182 if ( mReplacedPattern ) {
183 mPatterns[mPatternEndIndex] = mReplacedPattern;
184 mReplacedPattern = 0;
186 mChunkSize = std::min( chunksize, mNumPatterns );
187 mPatternStartIndex = 0;
188 mPatternEndIndex = mChunkSize;
189 mReplacedPattern = mPatterns[mPatternEndIndex];
190 mPatterns[mPatternEndIndex] = 0;
194 InvarianceChecker check(
this );
195 if ( mReplacedPattern ) {
196 mPatterns[mPatternEndIndex] = mReplacedPattern;
197 mReplacedPattern = 0;
199 mPatternStartIndex += mChunkSize;
200 mPatternEndIndex += mChunkSize;
201 if ( mPatternEndIndex < mNumPatterns ) {
202 mReplacedPattern = mPatterns[mPatternEndIndex];
203 mPatterns[mPatternEndIndex] = 0;
209 InvarianceChecker check(
this );
210 if ( mPatternStartIndex < mNumPatterns )
211 return mPatterns + mPatternStartIndex;
216 mCtx->clearSigningKeys();
217 for ( std::vector<GpgME::Key>::const_iterator it = signers.begin() ; it != signers.end() ; ++it ) {
218 if ( (*it).isNull() )
220 if (
const GpgME::Error err = mCtx->addSigningKey( *it ) )
227 mInDataDataProvider =
new QGpgME::TQByteArrayDataProvider( in );
228 mInData =
new GpgME::Data( mInDataDataProvider );
229 assert( !mInData->isNull() );
233 mOutDataDataProvider =
new QGpgME::TQByteArrayDataProvider();
234 mOutData =
new GpgME::Data( mOutDataDataProvider );
235 assert( !mOutData->isNull() );
238 static const unsigned int GetAuditLogFlags = GpgME::Context::AuditLogWithHelp|GpgME::Context::HtmlAuditLog;
240 static TQString audit_log_as_html( GpgME::Context * ctx, GpgME::Error & err ) {
242 QGpgME::TQByteArrayDataProvider dp;
243 GpgME::Data data( &dp );
244 assert( !data.isNull() );
245 if ( ( err = ctx->getAuditLog( data, GetAuditLogFlags ) ) )
247 const TQByteArray ba = dp.data();
248 return TQString::fromUtf8( ba.data(), ba.size() );
252 if ( context == mCtx ) {
254 doOperationDoneEvent( e );
255 mThis->deleteLater();
262 mAuditLogAsHtml = audit_log_as_html( mCtx, mAuditLogError );
265 void Kleo::QGpgMEJob::doSlotCancel() {
266 mCtx->cancelPendingOperation();
269 void Kleo::QGpgMEJob::showProgress(
const char * what,
int type,
int current,
int total ) {
270 doEmitProgressSignal( QGpgMEProgressTokenMapper::instance()->map( what, type, current, total ), current, total );
273 char * Kleo::QGpgMEJob::getPassphrase(
const char * useridHint,
const char * ,
274 bool previousWasBad,
bool & canceled ) {
277 TQString msg = previousWasBad ?
278 i18n(
"You need a passphrase to unlock the secret key for user:<br/> %1 (retry)" ) :
279 i18n(
"You need a passphrase to unlock the secret key for user:<br/> %1" );
280 msg = msg.arg( TQString::fromUtf8( useridHint ) ) +
"<br/><br/>";
281 msg.prepend(
"<qt>" );
282 msg += i18n(
"This dialog will reappear every time the passphrase is needed. For a more secure solution that also allows caching the passphrase, use gpg-agent." ) +
"<br/>";
283 const TQString gpgAgent = TDEStandardDirs::findExe(
"gpg-agent" );
284 if ( !gpgAgent.isEmpty() ) {
285 msg += i18n(
"gpg-agent was found in %1, but does not appear to be running." )
288 msg += i18n(
"gpg-agent is part of gnupg-%1, which you can download from %2" )
290 .arg(
"http://www.gnupg.org/download" );
293 msg += i18n(
"For information on how to set up gpg-agent, see %1" )
294 .arg(
"http://userbase.kde.org/KMail/PGP_MIME" );
296 msg += i18n(
"Enter passphrase:" );
297 Kleo::PassphraseDialog dlg( msg, i18n(
"Passphrase Dialog") );
298 if ( dlg.exec() != TQDialog::Accepted ) {
304 return strdup( dlg.passphrase().utf8() );
An abstract base class for asynchronous crypto operations.
This is a hackish helper class to avoid code duplication in this backend's Kleo::Job subclasses.
void doSlotOperationDoneEvent(GpgME::Context *context, const GpgME::Error &e)
const char ** nextChunk()
void setPatterns(const TQStringList &sl, bool allowEmpty=false)
GpgME::Error setSigningKeys(const std::vector< GpgME::Key > &signers)
void setChunkSize(unsigned int size)
void hookupContextToEventLoopInteractor()
void createInData(const TQByteArray &in)
const char ** patterns() const