• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeutils API Reference
  • KDE Home
  • Contact Us
 

kgpg

  • sources
  • kde-4.12
  • kdeutils
  • kgpg
caff.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009,2010,2012,2013,2014 Rolf Eike Beer <kde@opensource.sf-tec.de>
3  */
4 
5 /***************************************************************************
6  * *
7  * This program is free software; you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or *
10  * (at your option) any later version. *
11  * *
12  ***************************************************************************/
13 
14 #include "caff.h"
15 #include "caff_p.h"
16 
17 #include "kgpginterface.h"
18 #include "kgpgsettings.h"
19 #include "core/KGpgKeyNode.h"
20 #include "core/KGpgSignableNode.h"
21 #include "transactions/kgpgdeluid.h"
22 #include "transactions/kgpgencrypt.h"
23 #include "transactions/kgpgexport.h"
24 #include "transactions/kgpgimport.h"
25 #include "transactions/kgpgsignuid.h"
26 
27 #include <KDebug>
28 #include <KLocale>
29 #include <KProcess>
30 #include <KTempDir>
31 #include <KTemporaryFile>
32 #include <KToolInvocation>
33 #include <QDir>
34 #include <QFileInfo>
35 
36 KGpgCaffPrivate::KGpgCaffPrivate(KGpgCaff *parent, const KGpgSignableNode::List &ids, const QStringList &signers,
37  const KGpgCaff::OperationFlags flags, const KGpgSignTransactionHelper::carefulCheck checklevel)
38  : QObject(parent),
39  q_ptr(parent),
40  m_signers(signers),
41  m_flags(flags),
42  m_checklevel(checklevel),
43  m_allids(ids)
44 {
45  const QString gpgCfg = KGpgSettings::gpgConfigPath();
46  const QString secring = KgpgInterface::getGpgSetting(QLatin1String( "secret-keyring" ), gpgCfg);
47 
48  if (!secring.isEmpty()) {
49  m_secringfile = secring;
50  } else {
51  QFileInfo fn(gpgCfg);
52  fn.setFile(fn.dir(), QLatin1String("secring.gpg"));
53  m_secringfile = QDir::toNativeSeparators(fn.absoluteFilePath());
54  }
55 }
56 
57 KGpgCaffPrivate::~KGpgCaffPrivate()
58 {
59 }
60 
61 void
62 KGpgCaffPrivate::reexportKey(const KGpgSignableNode *key)
63 {
64  Q_ASSERT(m_tempdir.isNull());
65  m_tempdir.reset(new KTempDir());
66 
67  // export all keys necessary for signing
68  QStringList exportkeys(m_signers);
69  exportkeys << key->getKeyNode()->getId();
70 
71  KGpgImport *imp = new KGpgImport(this);
72 
73  QStringList expOptions(QLatin1String( "--export-options" ));
74  expOptions << QLatin1String( "export-clean,export-attribute" );
75  KGpgExport *exp = new KGpgExport(this, exportkeys, expOptions);
76  exp->setOutputTransaction(imp);
77 
78  imp->setGnuPGHome(m_tempdir->name());
79 
80  connect(imp, SIGNAL(done(int)), SLOT(slotReimportDone(int)));
81  imp->start();
82 }
83 
84 void
85 KGpgCaffPrivate::slotReimportDone(int result)
86 {
87  KGpgImport *imp = qobject_cast<KGpgImport *>(sender());
88 
89  if (result != KGpgTransaction::TS_OK) {
90  abortOperation(result);
91  } else {
92  bool ret = (imp->getImportedIds(0x1).count() == 1 + m_signers.count());
93 
94  if (!ret) {
95  abortOperation(-1);
96  } else {
97  KGpgSignUid *signuid = new KGpgSignUid(this, m_signers.first(), m_allids.first(), false, m_checklevel);
98  signuid->setGnuPGHome(m_tempdir->name());
99  signuid->setSecringFile(m_secringfile);
100  connect(signuid, SIGNAL(done(int)), SLOT(slotSigningFinished(int)));
101 
102  signuid->start();
103  }
104  }
105 
106  sender()->deleteLater();
107 }
108 
109 void
110 KGpgCaffPrivate::abortOperation(int result)
111 {
112  Q_Q(KGpgCaff);
113 
114  kDebug(2100) << "transaction" << sender() << "failed, result" << result;
115  m_tempdir.reset();
116 
117  emit q->aborted();
118 }
119 
120 void
121 KGpgCaffPrivate::checkNextLoop()
122 {
123  Q_Q(KGpgCaff);
124 
125  m_tempdir.reset();
126 
127  if (m_allids.isEmpty())
128  emit q->done();
129  else
130  reexportKey(m_allids.first());
131 }
132 
133 void
134 KGpgCaffPrivate::slotSigningFinished(int result)
135 {
136  sender()->deleteLater();
137 
138  if (result != KGpgTransaction::TS_OK) {
139  if ((result == KGpgSignTransactionHelper::TS_ALREADY_SIGNED) && (m_flags & KGpgCaff::IgnoreAlreadySigned)) {
140  m_allids.removeFirst();
141  checkNextLoop();
142  } else {
143  abortOperation(result);
144  }
145  return;
146  }
147 
148  const KGpgSignableNode *uid = m_allids.first();
149 
150  // if there is no email address we can't send this out anyway, so don't bother.
151  // could be improved: if this is the only selected uid from this key go and select
152  // a proper mail address to send this to
153  if (uid->getEmail().isEmpty()) {
154  m_allids.removeFirst();
155  checkNextLoop();
156  }
157 
158  const KGpgKeyNode *key = uid->getKeyNode();
159 
160  int uidnum;
161 
162  if (uid == key) {
163  uidnum = -1;
164  } else {
165  uidnum = -uid->getId().toInt();
166  }
167 
168  KGpgDelUid::RemoveMode removeMode;
169  switch (KGpgSettings::mailUats()) {
170  case 0:
171  removeMode = KGpgDelUid::RemoveWithEmail;
172  break;
173  case 1:
174  if (uid == key) {
175  removeMode = KGpgDelUid::RemoveWithEmail;
176  } else {
177  // check if this is the first uid with email address
178  const KGpgSignableNode *otherUid;
179  int index = 1;
180  removeMode = KGpgDelUid::RemoveAllOther;
181 
182  while ( (otherUid = key->getUid(index++)) != NULL) {
183  if (otherUid == uid) {
184  removeMode = KGpgDelUid::RemoveWithEmail;
185  break;
186  }
187  if (!otherUid->getEmail().isEmpty())
188  break;
189  }
190  }
191  break;
192  case 2:
193  removeMode = KGpgDelUid::RemoveAllOther;
194  break;
195  default:
196  Q_ASSERT(0);
197  return;
198  }
199 
200  KGpgDelUid *deluid = new KGpgDelUid(this, key, uidnum, removeMode);
201 
202  deluid->setGnuPGHome(m_tempdir->name());
203 
204  connect(deluid, SIGNAL(done(int)), SLOT(slotDelUidFinished(int)));
205 
206  deluid->start();
207 }
208 
209 void
210 KGpgCaffPrivate::slotDelUidFinished(int result)
211 {
212  sender()->deleteLater();
213 
214  const KGpgSignableNode *uid = m_allids.first();
215  const KGpgKeyNode *key = uid->getKeyNode();
216 
217  if (result != KGpgTransaction::TS_OK) {
218  // it's no error if we tried to delete all other ids but there is no other id
219  if ((uid != key) || (result != KGpgDelUid::TS_NO_SUCH_UID)) {
220  abortOperation(result);
221  return;
222  }
223  }
224 
225  QStringList expOptions(QLatin1String( "--export-options" ));
226  expOptions << QLatin1String( "export-attribute" );
227 
228  KGpgExport *exp = new KGpgExport(this, QStringList(key->getId()), expOptions);
229 
230  exp->setGnuPGHome(m_tempdir->name());
231 
232  connect(exp, SIGNAL(done(int)), SLOT(slotExportFinished(int)));
233 
234  exp->start();
235 }
236 
237 void
238 KGpgCaffPrivate::slotExportFinished(int result)
239 {
240  sender()->deleteLater();
241 
242  if (result != KGpgTransaction::TS_OK) {
243  abortOperation(result);
244  return;
245  }
246 
247  const KGpgSignableNode *uid = m_allids.first();
248  const KGpgKeyNode *key = uid->getKeyNode();
249 
250  KGpgExport *exp = qobject_cast<KGpgExport *>(sender());
251  Q_ASSERT(exp != NULL);
252 
253  QString body = KGpgSettings::emailTemplate();
254  body.replace(QLatin1Char( '%' ) + i18nc("Email template placeholder for key id", "KEYID") + QLatin1Char( '%' ), key->getId());
255  body.replace(QLatin1Char( '%' ) + i18nc("Email template placeholder for key id", "UIDNAME") + QLatin1Char( '%' ), uid->getNameComment());
256 
257  body += QLatin1Char( '\n' ) + QLatin1String( exp->getOutputData() );
258 
259  KGpgEncrypt *enc = new KGpgEncrypt(this, QStringList(key->getId()), body, KGpgEncrypt::AsciiArmored | KGpgEncrypt::AllowUntrustedEncryption);
260 
261  // Set the home directory to make sure custom encrypt options
262  // as well as the "always encrypt to" setting are not honored.
263  enc->setGnuPGHome(m_tempdir->name());
264 
265  connect(enc, SIGNAL(done(int)), SLOT(slotTextEncrypted(int)));
266 
267  enc->start();
268 }
269 
270 void
271 KGpgCaffPrivate::slotTextEncrypted(int result)
272 {
273  sender()->deleteLater();
274 
275  switch (result) {
276  case KGpgTransaction::TS_OK: {
277  KGpgEncrypt *enc = qobject_cast<KGpgEncrypt *>(sender());
278  Q_ASSERT(enc != NULL);
279 
280  const QString text = enc->encryptedText().join(QLatin1String("\n"));
281 
282  const KGpgSignableNode *uid = m_allids.takeFirst();
283 
284  const QString email = uid->getEmail();
285  const QString keyid = uid->getKeyNode()->getId();
286 
287  KToolInvocation::invokeMailer(email, QString(), QString(),
288  i18nc("%1 is 64 bit key id (in hex), text is used as email subject", "Your key %1", keyid),
289  text);
290  break;
291  }
292  default:
293  abortOperation(result);
294  break;
295  case KGpgTransaction::TS_USER_ABORTED:
296  m_allids.clear();
297  break;
298  }
299 
300  checkNextLoop();
301 }
302 
303 KGpgCaff::KGpgCaff(QObject *parent, const KGpgSignableNode::List &ids, const QStringList &signids,
304  const int checklevel, const OperationFlags flags)
305  : QObject(parent),
306  d_ptr(new KGpgCaffPrivate(this, ids, signids, flags, static_cast<KGpgSignTransactionHelper::carefulCheck>(checklevel)))
307 {
308 }
309 
310 void
311 KGpgCaff::run()
312 {
313  Q_D(KGpgCaff);
314 
315  d->reexportKey(d->m_allids.first());
316 }
317 
318 #include "caff.moc"
319 #include "caff_p.moc"
KGpgCaff
Definition: caff.h:25
caff_p.h
KGpgCaff::run
void run()
Definition: caff.cpp:311
KGpgCaffPrivate::KGpgCaffPrivate
KGpgCaffPrivate(KGpgCaff *parent, const KGpgSignableNode::List &ids, const QStringList &signers, const KGpgCaff::OperationFlags flags, const KGpgSignTransactionHelper::carefulCheck checklevel)
Definition: caff.cpp:36
kgpgimport.h
KGpgSignTransactionHelper
helper class for key signing transactions
Definition: kgpgsigntransactionhelper.h:25
KGpgSettings::mailUats
static int mailUats()
Get Mail_Uats.
Definition: kgpgsettings.h:972
KGpgKeyNode::getUid
const KGpgSignableNode * getUid(const unsigned int index) const
get the user id or user attribute with the given number
Definition: KGpgKeyNode.cpp:306
kgpgdeluid.h
KGpgTransaction::TS_OK
everything went fine
Definition: kgpgtransaction.h:60
KGpgExport::getOutputData
const QByteArray & getOutputData() const
return the data read from standard output
Definition: kgpgexport.cpp:117
KGpgSettings::gpgConfigPath
static QString gpgConfigPath()
Get The path of the gpg configuration file.
Definition: kgpgsettings.h:288
KGpgDelUid::RemoveMode
RemoveMode
Definition: kgpgdeluid.h:37
KGpgEncrypt::AsciiArmored
output the data as printable ASCII as opposed to binary data
Definition: kgpgencrypt.h:38
KGpgExport
export one or more keys from keyring
Definition: kgpgexport.h:32
KGpgNode::getNameComment
virtual QString getNameComment() const
Definition: KGpgNode.cpp:51
KGpgKeyNode::getId
virtual QString getId() const
Definition: KGpgKeyNode.cpp:113
KGpgImport
import one or more keys into the keyring
Definition: kgpgimport.h:31
KGpgDelUid::RemoveWithEmail
remove only those other uids that have an email address
Definition: kgpgdeluid.h:40
KGpgCaff::OperationFlags
OperationFlags
Definition: caff.h:33
KGpgSignUid
transaction class to sign a single user id of a key
Definition: kgpgsignuid.h:28
KGpgTransaction::start
void start()
Start the operation.
Definition: kgpgtransaction.cpp:390
QObject
KGpgDelUid
Definition: kgpgdeluid.h:27
KGpgKeyNode
A public key with or without corresponding secret key.
Definition: KGpgKeyNode.h:33
KGpgSignableNode::getKeyNode
virtual KGpgKeyNode * getKeyNode(void)=0
returns the key node this node belongs to
KGpgSettings::emailTemplate
static QString emailTemplate()
Get This is the text of the email sent by the "Sign and Mail User ID" action.
Definition: kgpgsettings.h:953
KGpgCaff::IgnoreAlreadySigned
uids that are already signed will not be mailed again
Definition: caff.h:35
KGpgSignTransactionHelper::TS_ALREADY_SIGNED
user id is alredy signed by given key
Definition: kgpgsigntransactionhelper.h:46
kgpgencrypt.h
kgpginterface.h
kgpgexport.h
kgpgsignuid.h
KGpgSignableNode::List
QList< KGpgSignableNode * > List
Definition: KGpgSignableNode.h:36
KGpgDelUid::RemoveAllOther
remove all other uids
Definition: kgpgdeluid.h:38
KGpgCaffPrivate::m_allids
KGpgSignableNode::List m_allids
Definition: caff_p.h:50
KGpgEncrypt::encryptedText
QStringList encryptedText() const
get decryption result
Definition: kgpgencrypt.cpp:81
KGpgCaffPrivate
Definition: caff_p.h:29
KGpgTransaction::TS_USER_ABORTED
the user aborted the transaction
Definition: kgpgtransaction.h:63
kgpgsettings.h
KGpgSignTransactionHelper::setSecringFile
void setSecringFile(const QString &filename)
add a secret keyring file
Definition: kgpgsigntransactionhelper.cpp:136
KGpgCaff::KGpgCaff
KGpgCaff(QObject *parent, const KGpgSignableNode::List &ids, const QStringList &signids, const int checklevel=0, const OperationFlags flags=DefaultMode)
create a new object to sign and mail key ids
Definition: caff.cpp:303
KGpgNode::getId
virtual QString getId() const
Definition: KGpgNode.cpp:318
KGpgKeyNode.h
KGpgNode::getEmail
virtual QString getEmail() const
Definition: KGpgNode.cpp:300
caff.h
KGpgImport::getImportedIds
static QStringList getImportedIds(const QStringList &log, const int reason=-1)
get the full fingerprints of the imported keys
Definition: kgpgimport.cpp:59
KGpgExport::setOutputTransaction
void setOutputTransaction(KGpgTransaction *outt)
set the transaction the output is sent to
Definition: kgpgexport.cpp:102
KGpgSignableNode.h
KGpgDelUid::TS_NO_SUCH_UID
user id does not exist
Definition: kgpgdeluid.h:34
KGpgCaffPrivate::~KGpgCaffPrivate
~KGpgCaffPrivate()
Definition: caff.cpp:57
KGpgSignTransactionHelper::carefulCheck
carefulCheck
Definition: kgpgsigntransactionhelper.h:38
KGpgEncrypt
encrypt the given text or files
Definition: kgpgencrypt.h:30
KGpgTransaction::setGnuPGHome
void setGnuPGHome(const QString &home)
sets the home directory of GnuPG called for this transaction
Definition: kgpgtransaction.cpp:663
KGpgSignableNode
An object that may have KGpgSignNode children.
Definition: KGpgSignableNode.h:31
KgpgInterface::getGpgSetting
QString getGpgSetting(const QString &name, const QString &configfile)
Definition: kgpginterface.cpp:37
KGpgEncrypt::AllowUntrustedEncryption
allow encryption with untrusted keys, ignored for symmetric encryption
Definition: kgpgencrypt.h:39
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:07:51 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kgpg

Skip menu "kgpg"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeutils API Reference

Skip menu "kdeutils API Reference"
  • ark
  • filelight
  • kcalc
  • kcharselect
  • kdf
  • kfloppy
  • kgpg
  • kremotecontrol
  • ktimer
  • kwallet
  • superkaramba
  • sweeper

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal