33 #include <config-kleopatra.h>
42 #include <kleo/stl_util.h>
43 #include <kleo/cryptobackendfactory.h>
44 #include <kleo/cryptobackend.h>
45 #include <kleo/signjob.h>
47 #include <gpgme++/signingresult.h>
48 #include <gpgme++/key.h>
53 #include <QTextDocument>
55 #include <boost/bind.hpp>
56 #include <boost/mem_fn.hpp>
59 using namespace Kleo::Crypto;
60 using namespace boost;
61 using namespace GpgME;
66 const SigningResult m_result;
69 explicit SignEMailResult(
const SigningResult & r,
const AuditLog & auditLog )
70 :
Task::Result(), m_result( r ), m_auditLog( auditLog ) {}
72 QString overview()
const;
73 QString details()
const;
74 int errorCode()
const;
75 QString errorString()
const;
76 VisualCode code()
const;
80 QString makeResultString(
const SigningResult& res )
82 const Error err = res.error();
84 if ( err.isCanceled() )
85 return i18n(
"Signing canceled." );
88 return i18n(
"Signing failed: %1", Qt::escape( QString::fromLocal8Bit( err.asString() ) ) );
90 return i18n(
"Signing succeeded." );
94 class SignEMailTask::Private {
95 friend class ::Kleo::Crypto::SignEMailTask;
101 std::auto_ptr<Kleo::SignJob> createJob( GpgME::Protocol proto );
104 void slotResult(
const SigningResult & );
109 std::vector<Key> signers;
115 QPointer<Kleo::SignJob> job;
132 :
Task( p ),
d( new Private( this ) )
154 kleo_assert( kdtools::none_of( signers, mem_fn( &Key::isNull ) ) );
155 d->signers = signers;
160 d->detached = detached;
161 d->clearsign =
false;
166 d->clearsign = clear;
172 return d->signers.front().protocol();
177 return d->input ? d->input->label() : QString();
180 unsigned long long SignEMailTask::inputSize()
const
182 return d->input ? d->input->size() : 0;
185 void SignEMailTask::doStart() {
193 std::auto_ptr<Kleo::SignJob> job = d->createJob(
protocol() );
196 job->start( d->signers,
197 d->input->ioDevice(), d->output->ioDevice(),
198 d->clearsign ? GpgME::Clearsigned : d->detached ?
GpgME::Detached : GpgME::NormalSignatureMode );
200 d->job = job.release();
205 d->job->slotCancel();
208 std::auto_ptr<Kleo::SignJob> SignEMailTask::Private::createJob( GpgME::Protocol proto ) {
209 const CryptoBackend::Protocol *
const backend = CryptoBackendFactory::instance()->protocol( proto );
211 bool shouldArmor = ( proto ==
OpenPGP ||
q->asciiArmor() ) && !output->binaryOpt();
212 std::auto_ptr<Kleo::SignJob> signJob( backend->signJob( shouldArmor,
false ) );
214 if ( proto ==
CMS && !
q->asciiArmor() && !output->binaryOpt() )
215 signJob->setOutputIsBase64Encoded(
true );
216 connect( signJob.get(), SIGNAL(progress(QString,
int,
int)),
217 q, SLOT(setProgress(QString,
int,
int)) );
218 connect( signJob.get(), SIGNAL(result(GpgME::SigningResult,QByteArray)),
219 q, SLOT(slotResult(GpgME::SigningResult)) );
223 static QString
collect_micalgs(
const GpgME::SigningResult & result, GpgME::Protocol proto ) {
224 const std::vector<GpgME::CreatedSignature> css = result.createdSignatures();
226 #ifndef DASHBOT_HAS_STABLE_COMPILER
227 Q_FOREACH(
const GpgME::CreatedSignature & sig, css )
228 micalgs.push_back( QString::fromLatin1( sig.hashAlgorithmAsString() ).toLower() );
230 std::transform( css.begin(), css.end(),
231 std::back_inserter( micalgs ),
232 boost::bind( &QString::toLower, boost::bind( &QString::fromLatin1, boost::bind( &GpgME::CreatedSignature::hashAlgorithmAsString, _1 ), -1 ) ) );
235 for ( QStringList::iterator it = micalgs.begin(), end = micalgs.end() ; it != end ; ++it )
236 it->prepend( QLatin1String(
"pgp-") );
238 micalgs.erase( std::unique( micalgs.begin(), micalgs.end() ), micalgs.end() );
239 return micalgs.join( QLatin1String(
",") );
242 void SignEMailTask::Private::slotResult(
const SigningResult & result ) {
243 const Job *
const job = qobject_cast<
const Job*>(
q->sender() );
244 if ( result.error().code() ) {
258 QString SignEMailResult::overview()
const {
259 return makeOverview( makeResultString( m_result ) );
262 QString SignEMailResult::details()
const {
266 int SignEMailResult::errorCode()
const {
267 return m_result.error().encodedError();
270 QString SignEMailResult::errorString()
const {
271 return hasError() ? makeResultString( m_result ) : QString();
275 if ( m_result.error().isCanceled() )
277 return m_result.error().code() ? NeutralError : NeutralSuccess;
280 AuditLog SignEMailResult::auditLog()
const {
284 #include "moc_signemailtask.cpp"
static QString collect_micalgs(const GpgME::SigningResult &result, GpgME::Protocol proto)
void setInput(const boost::shared_ptr< Input > &input)
GpgME::Protocol protocol() const
void setSigners(const std::vector< GpgME::Key > &recipients)
static AuditLog fromJob(const Job *)
void setClearsign(bool clear)
#define kleo_assert(cond)
void setDetachedSignature(bool detached)
SignEMailTask(QObject *parent=0)
void setOutput(const boost::shared_ptr< Output > &output)