2
Copyright (C) 2009 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.net
3
Copyright (c) 2009 Leo Franchi <lfranchi@kde.org>
5
This library is free software; you can redistribute it and/or modify it
6
under the terms of the GNU Library General Public License as published by
7
the Free Software Foundation; either version 2 of the License, or (at your
8
option) any later version.
10
This library is distributed in the hope that it will be useful, but WITHOUT
11
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13
License for more details.
15
You should have received a copy of the GNU Library General Public License
16
along with this library; see the file COPYING.LIB. If not, write to the
17
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23
#include "contentjobbase_p.h"
24
#include "kleo/cryptobackendfactory.h"
25
#include "kleo/cryptobackend.h"
26
#include "kleo/enum.h"
27
#include "kleo/signjob.h"
31
#include <kmime/kmime_message.h>
32
#include <kmime/kmime_content.h>
33
#include <kmime/kmime_util.h>
36
#include <gpgme++/global.h>
37
#include <gpgme++/signingresult.h>
38
#include <gpgme++/encryptionresult.h>
41
using namespace Message;
43
class Message::SignJobPrivate : public ContentJobBasePrivate
46
SignJobPrivate( SignJob *qq )
47
: ContentJobBasePrivate( qq )
52
KMime::Content* content;
53
std::vector<GpgME::Key> signers;
54
Kleo::CryptoMessageFormat format;
56
// copied from messagecomposer.cpp
57
bool binaryHint( Kleo::CryptoMessageFormat f )
60
case Kleo::SMIMEFormat:
61
case Kleo::SMIMEOpaqueFormat:
64
case Kleo::OpenPGPMIMEFormat:
65
case Kleo::InlineOpenPGPFormat:
71
GpgME::SignatureMode signingMode( Kleo::CryptoMessageFormat f )
74
case Kleo::SMIMEOpaqueFormat:
75
return GpgME::NormalSignatureMode;
76
case Kleo::InlineOpenPGPFormat:
77
return GpgME::Clearsigned;
79
case Kleo::SMIMEFormat:
80
case Kleo::OpenPGPMIMEFormat:
81
return GpgME::Detached;
85
Q_DECLARE_PUBLIC( SignJob )
88
SignJob::SignJob( QObject *parent )
89
: ContentJobBase( *new SignJobPrivate( this ), parent )
97
void SignJob::setContent( KMime::Content* content )
101
d->content = content;
104
void SignJob::setCryptoMessageFormat( Kleo::CryptoMessageFormat format)
108
// There *must* be a concrete format set at this point.
109
Q_ASSERT( format == Kleo::OpenPGPMIMEFormat
110
|| format == Kleo::InlineOpenPGPFormat
111
|| format == Kleo::SMIMEFormat
112
|| format == Kleo::SMIMEOpaqueFormat );
116
void SignJob::setSigningKeys( std::vector<GpgME::Key>& signers )
120
d->signers = signers;
123
KMime::Content* SignJob::origContent()
131
void SignJob::process()
134
Q_ASSERT( d->resultContent == 0 ); // Not processed before.
136
// if setContent hasn't been called, we assume that a subjob was added
137
// and we want to use that
139
Q_ASSERT( d->subjobContents.size() == 1 );
140
d->content = d->subjobContents.first();
143
d->resultContent = new KMime::Content;
145
const Kleo::CryptoBackend::Protocol *proto = 0;
146
if( d->format & Kleo::AnyOpenPGP ) {
147
proto = Kleo::CryptoBackendFactory::instance()->openpgp();
148
} else if( d->format & Kleo::AnySMIME ) {
149
proto = Kleo::CryptoBackendFactory::instance()->smime();
155
kDebug() << "creating signJob from:" << proto->name() << proto->displayName();
156
std::auto_ptr<Kleo::SignJob> job( proto->signJob( !d->binaryHint( d->format ), d->format == Kleo::InlineOpenPGPFormat ) );
157
// for now just do the main recipients
158
QByteArray signature;
160
// replace simple LFs by CRLFs for all MIME supporting CryptPlugs
161
// according to RfC 2633, 3.1.1 Canonicalization
162
d->content->assemble();
166
if( d->format & Kleo::InlineOpenPGPFormat &&
167
!( d->format & Kleo::SMIMEOpaqueFormat ) ) {
168
content = KMime::LFtoCRLF( d->content->body() );
169
} else if( !( d->format & Kleo::SMIMEOpaqueFormat ) ) {
170
content = KMime::LFtoCRLF( d->content->encodedContent() );
171
} else { // SMimeOpaque doesn't need LFtoCRLF, else it gets munged
172
content = d->content->encodedContent();
175
// FIXME: Make this async
176
GpgME::SigningResult res = job->exec( d->signers,
178
d->signingMode( d->format ),
182
kDebug() << "signing failed:" << res.error().asString();
183
// job->showErrorDialog( globalPart()->parentWidgetForGui() );
184
setError( res.error().code() );
185
setErrorText( QString::fromLocal8Bit( res.error().asString() ) );
188
// exec'ed jobs don't delete themselves
191
QByteArray signatureHashAlgo = res.createdSignature( 0 ).hashAlgorithmAsString();
193
d->resultContent = Message::Util::composeHeadersAndBody( d->content, signature, d->format, true, signatureHashAlgo );
197
#include "signjob.moc"