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

kgpg

  • sources
  • kde-4.14
  • kdeutils
  • kgpg
kgpginterface.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2002 Jean-Baptiste Mardelle <bj@altern.org>
3  * Copyright (C) 2007,2008,2009,2010,2011,2012,2013
4  * Rolf Eike Beer <kde@opensource.sf-tec.de>
5  */
6 /***************************************************************************
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  ***************************************************************************/
14 
15 #include "kgpginterface.h"
16 
17 #include "gpgproc.h"
18 #include "core/convert.h"
19 #include "core/KGpgKeyNode.h"
20 #include "core/KGpgSignNode.h"
21 #include "core/KGpgSubkeyNode.h"
22 #include "core/KGpgUatNode.h"
23 #include "core/KGpgUidNode.h"
24 
25 #include <gpgme.h>
26 #include <KConfig>
27 #include <KDebug>
28 #include <KGlobal>
29 #include <KLocale>
30 #include <KMessageBox>
31 #include <KProcess>
32 #include <QFile>
33 #include <QString>
34 #include <QTextStream>
35 
36 using namespace KgpgCore;
37 
38 QString KgpgInterface::getGpgSetting(const QString &name, const QString &configfile)
39 {
40  const QString tmp(name.simplified() + QLatin1Char( ' ' ));
41  QFile qfile(configfile);
42 
43  if (qfile.open(QIODevice::ReadOnly) && (qfile.exists())) {
44  QTextStream t(&qfile);
45  while (!t.atEnd()) {
46  QString result(t.readLine().simplified());
47  if (result.startsWith(tmp)) {
48  result = result.mid(tmp.length()).simplified();
49  return result.section(QLatin1Char( ' ' ), 0, 0);
50  }
51  }
52  qfile.close();
53  }
54 
55  return QString();
56 }
57 
58 void KgpgInterface::setGpgSetting(const QString &name, const QString &value, const QString &url)
59 {
60  QFile qfile(url);
61 
62  if (qfile.open(QIODevice::ReadOnly) && (qfile.exists())) {
63  const QString temp(name + QLatin1Char( ' ' ));
64  QString texttowrite;
65  bool found = false;
66  QTextStream t(&qfile);
67 
68  while (!t.atEnd()) {
69  QString result = t.readLine();
70  if (result.simplified().startsWith(temp)) {
71  if (!value.isEmpty())
72  result = temp + QLatin1Char( ' ' ) + value;
73  else
74  result.clear();
75  found = true;
76  }
77 
78  texttowrite += result + QLatin1Char( '\n' );
79  }
80 
81  qfile.close();
82  if ((!found) && (!value.isEmpty()))
83  texttowrite += QLatin1Char( '\n' ) + temp + QLatin1Char( ' ' ) + value;
84 
85  if (qfile.open(QIODevice::WriteOnly)) {
86  QTextStream t(&qfile);
87  t << texttowrite;
88  qfile.close();
89  }
90  }
91 }
92 
93 bool KgpgInterface::getGpgBoolSetting(const QString &name, const QString &configfile)
94 {
95  QFile qfile(configfile);
96  if (qfile.open(QIODevice::ReadOnly) && (qfile.exists())) {
97  QTextStream t(&qfile);
98  while (!t.atEnd()) {
99  if (t.readLine().simplified().startsWith(name))
100  return true;
101  }
102  qfile.close();
103  }
104  return false;
105 }
106 
107 void KgpgInterface::setGpgBoolSetting(const QString &name, const bool enable, const QString &url)
108 {
109  QFile qfile(url);
110 
111  if (qfile.open(QIODevice::ReadOnly) && (qfile.exists())) {
112  QString texttowrite;
113  bool found = false;
114  QTextStream t(&qfile);
115 
116  while (!t.atEnd()) {
117  QString result(t.readLine());
118 
119  if (result.simplified().startsWith(name)) {
120  if (enable)
121  result = name;
122  else
123  result.clear();
124 
125  found = true;
126  }
127 
128  texttowrite += result + QLatin1Char( '\n' );
129  }
130  qfile.close();
131 
132  if ((!found) && (enable))
133  texttowrite += name;
134 
135  if (qfile.open(QIODevice::WriteOnly)) {
136  QTextStream t(&qfile);
137  t << texttowrite;
138  qfile.close();
139  }
140  }
141 }
142 
147 static KgpgCore::KgpgKeyList
148 readPublicKeysProcess(GPGProc &p, KGpgKeyNode *readNode)
149 {
150  QStringList lsp;
151  int items;
152  KgpgCore::KgpgKeyList publiclistkeys;
153  KgpgCore::KgpgKey *publickey = NULL;
154  unsigned int idIndex = 0;
155  QString log;
156  KGpgSignableNode *currentSNode = NULL;
157 
158  while ((items = p.readln(lsp)) >= 0) {
159  if ((lsp.at(0) == QLatin1String( "pub" )) && (items >= 10)) {
160  KgpgSubKeyType subtype;
161  KgpgSubKeyType keytype;
162  bool enabled = true;
163  if (items > 11) {
164  const QString &caps = lsp.at(11);
165 
166  enabled = !caps.contains(QLatin1Char('D'), Qt::CaseSensitive);
167 
168  subtype = Convert::toSubType(caps, false);
169  keytype = Convert::toSubType(caps, true);
170  }
171 
172  publiclistkeys << KgpgKey(lsp.at(4), lsp.at(2).toUInt(), Convert::toTrust(lsp.at(1)),
173  Convert::toAlgo(lsp.at(3).toInt()), subtype, keytype,
174  QDateTime::fromTime_t(lsp.at(5).toUInt()));
175 
176  publickey = &publiclistkeys.last();
177 
178  const QString &owTrust = lsp.at(8);
179  if (owTrust.isEmpty())
180  publickey->setOwnerTrust(GPGME_VALIDITY_UNDEFINED);
181  else
182  publickey->setOwnerTrust(Convert::toOwnerTrust(owTrust[0]));
183 
184  const QString &endDate = lsp.at(6);
185  if (endDate.isEmpty())
186  publickey->setExpiration(QDateTime());
187  else
188  publickey->setExpiration(QDateTime::fromTime_t(endDate.toUInt()));
189 
190  publickey->setValid(enabled); // disabled key
191 
192  idIndex = 0;
193  } else if (publickey && (lsp.at(0) == QLatin1String( "fpr" )) && (items >= 10)) {
194  const QString fingervalue(lsp.at(9));
195 
196  // there may also be fingerprints reported for subkeys
197  if (publickey->fingerprint().isEmpty())
198  publickey->setFingerprint(fingervalue);
199  } else if (publickey && (lsp.at(0) == QLatin1String( "sub" )) && (items >= 7)) {
200  KgpgSubKeyType subtype;
201 
202  if (items > 11)
203  subtype = Convert::toSubType(lsp.at(11), false);
204 
205  KgpgKeySub sub(lsp.at(4), lsp.at(2).toUInt(), Convert::toTrust(lsp.at(1)),
206  Convert::toAlgo(lsp.at(3).toInt()), subtype, QDateTime::fromTime_t(lsp.at(5).toUInt()));
207 
208  // FIXME: Please see kgpgkey.h, KgpgSubKey class
209  if (items <= 11)
210  sub.setValid(true);
211  else
212  sub.setValid(!lsp.at(11).contains(QLatin1Char( 'D' )));
213 
214  if (lsp.at(6).isEmpty())
215  sub.setExpiration(QDateTime());
216  else
217  sub.setExpiration(QDateTime::fromTime_t(lsp.at(6).toUInt()));
218 
219  publickey->subList()->append(sub);
220  if (readNode == NULL)
221  currentSNode = NULL;
222  else
223  currentSNode = new KGpgSubkeyNode(readNode, sub);
224  } else if (publickey && (lsp.at(0) == QLatin1String( "uat" ))) {
225  idIndex++;
226  if (readNode != NULL) {
227  currentSNode = new KGpgUatNode(readNode, idIndex, lsp);
228  }
229  } else if (publickey && (lsp.at(0) == QLatin1String( "uid" )) && (items >= 10)) {
230  if (idIndex == 0) {
231  QString fullname(lsp.at(9));
232  QString kmail;
233  if (fullname.contains(QLatin1Char( '<' )) ) {
234  kmail = fullname;
235 
236  if (fullname.contains(QLatin1Char( ')' )) )
237  kmail = kmail.section(QLatin1Char( ')' ), 1);
238 
239  kmail = kmail.section(QLatin1Char( '<' ), 1);
240  kmail.truncate(kmail.length() - 1);
241 
242  if (kmail.contains(QLatin1Char( '<' ))) {
243  // several email addresses in the same key
244  kmail = kmail.replace(QLatin1Char( '>' ), QLatin1Char( ';' ));
245  kmail.remove(QLatin1Char( '<' ));
246  }
247  }
248 
249  QString kname(fullname.section( QLatin1String( " <" ), 0, 0));
250  QString comment;
251  if (fullname.contains(QLatin1Char( '(' )) ) {
252  kname = kname.section( QLatin1String( " (" ), 0, 0);
253  comment = fullname.section(QLatin1Char( '(' ), 1, 1);
254  comment = comment.section(QLatin1Char( ')' ), 0, 0);
255  }
256 
257  idIndex++;
258  publickey->setEmail(kmail);
259  publickey->setComment(comment);
260  publickey->setName(kname);
261 
262  currentSNode = readNode;
263  } else {
264  idIndex++;
265  if (readNode != NULL) {
266  currentSNode = new KGpgUidNode(readNode, idIndex, lsp);
267  }
268  }
269  } else if (publickey && ((lsp.at(0) == QLatin1String( "sig" )) || (lsp.at(0) == QLatin1String( "rev" ))) && (items >= 11)) {
270  // there are no strings here that could have a recoded QLatin1Char( ':' ) in them
271  const QString signature = lsp.join(QLatin1String(":"));
272 
273  if (currentSNode != NULL)
274  (void) new KGpgSignNode(currentSNode, lsp);
275  } else {
276  log += lsp.join(QString(QLatin1Char( ':' ))) + QLatin1Char( '\n' );
277  }
278  }
279 
280  if (p.exitCode() != 0) {
281  KMessageBox::detailedError(NULL, i18n("An error occurred while scanning your keyring"), log);
282  log.clear();
283  }
284 
285  return publiclistkeys;
286 }
287 
288 KgpgKeyList KgpgInterface::readPublicKeys(const QStringList &ids)
289 {
290  GPGProc process;
291  process <<
292  QLatin1String("--with-colons") <<
293  QLatin1String("--with-fingerprint") <<
294  QLatin1String("--fixed-list-mode") <<
295  QLatin1String("--list-keys") <<
296  ids;
297 
298  process.setOutputChannelMode(KProcess::MergedChannels);
299 
300  process.start();
301  process.waitForFinished(-1);
302  return readPublicKeysProcess(process, NULL);
303 }
304 
305 void KgpgInterface::readSignatures(KGpgKeyNode *node)
306 {
307  GPGProc process;
308  process <<
309  QLatin1String("--with-colons") <<
310  QLatin1String("--with-fingerprint") <<
311  QLatin1String("--fixed-list-mode") <<
312  QLatin1String("--list-sigs") <<
313  node->getId();
314 
315  process.setOutputChannelMode(KProcess::MergedChannels);
316 
317  process.start();
318  process.waitForFinished(-1);
319 
320  readPublicKeysProcess(process, node);
321 }
322 
323 static KgpgCore::KgpgKeyList
324 readSecretKeysProcess(GPGProc &p)
325 {
326  QStringList lsp;
327  int items;
328  bool hasuid = false;
329  KgpgCore::KgpgKeyList result;
330  KgpgCore::KgpgKey *secretkey = NULL;
331 
332  while ( (items = p.readln(lsp)) >= 0 ) {
333  if ((lsp.at(0) == QLatin1String( "sec" )) && (items >= 10)) {
334  KgpgSubKeyType subtype;
335  KgpgSubKeyType keytype;
336 
337  if (items >= 11) {
338  const QString &caps = lsp.at(11);
339 
340  subtype = Convert::toSubType(caps, false);
341  keytype = Convert::toSubType(caps, true);
342  }
343 
344  result << KgpgKey(lsp.at(4), lsp.at(2).toUInt(), Convert::toTrust(lsp.at(1)),
345  Convert::toAlgo(lsp.at(3).toInt()), subtype, keytype,
346  QDateTime::fromTime_t(lsp.at(5).toUInt()));
347 
348  secretkey = &result.last();
349 
350  secretkey->setSecret(true);
351 
352  if (lsp.at(6).isEmpty())
353  secretkey->setExpiration(QDateTime());
354  else
355  secretkey->setExpiration(QDateTime::fromTime_t(lsp.at(6).toUInt()));
356  hasuid = true;
357  } else if ((lsp.at(0) == QLatin1String( "uid" )) && (items >= 10)) {
358  if (hasuid)
359  continue;
360 
361  hasuid = true;
362 
363  const QString fullname(lsp.at(9));
364  if (fullname.contains(QLatin1Char( '<' ) )) {
365  QString kmail(fullname);
366 
367  if (fullname.contains(QLatin1Char( ')' ) ))
368  kmail = kmail.section(QLatin1Char( ')' ), 1);
369 
370  kmail = kmail.section(QLatin1Char( '<' ), 1);
371  kmail.truncate(kmail.length() - 1);
372 
373  if (kmail.contains(QLatin1Char( '<' ) )) { // several email addresses in the same key
374  kmail = kmail.replace(QLatin1Char( '>' ), QLatin1Char( ';' ));
375  kmail.remove(QLatin1Char( '<' ));
376  }
377 
378  secretkey->setEmail(kmail);
379  } else {
380  secretkey->setEmail(QString());
381  }
382 
383  QString kname(fullname.section( QLatin1String( " <" ), 0, 0));
384  if (fullname.contains(QLatin1Char( '(' ) )) {
385  kname = kname.section( QLatin1String( " (" ), 0, 0);
386  QString comment = fullname.section(QLatin1Char( '(' ), 1, 1);
387  comment = comment.section(QLatin1Char( ')' ), 0, 0);
388 
389  secretkey->setComment(comment);
390  } else {
391  secretkey->setComment(QString());
392  }
393  secretkey->setName(kname);
394  } else if ((lsp.at(0) == QLatin1String( "fpr" )) && (items >= 10)) {
395  secretkey->setFingerprint(lsp.at(9));
396  }
397  }
398 
399  return result;
400 }
401 
402 KgpgKeyList KgpgInterface::readSecretKeys(const QStringList &ids)
403 {
404  GPGProc process;
405  process <<
406  QLatin1String("--with-colons") <<
407  QLatin1String("--list-secret-keys") <<
408  QLatin1String("--with-fingerprint") <<
409  QLatin1String("--fixed-list-mode") <<
410  ids;
411 
412  process.start();
413  process.waitForFinished(-1);
414  KgpgCore::KgpgKeyList result = readSecretKeysProcess(process);
415 
416  return result;
417 }
418 
419 #include "kgpginterface.moc"
KGpgUidNode.h
KGpgUatNode.h
KgpgCore::KgpgKey::setName
void setName(const QString &name)
Definition: kgpgkey.cpp:193
GPGProc
A interface to GnuPG handling UTF8 recoding correctly.
Definition: gpgproc.h:36
QString::truncate
void truncate(int position)
KgpgCore::KgpgKey::setFingerprint
void setFingerprint(const QString &fingerprint)
Definition: kgpgkey.cpp:208
KgpgInterface::setGpgBoolSetting
void setGpgBoolSetting(const QString &name, const bool enable, const QString &url)
Definition: kgpginterface.cpp:107
QTextStream::readLine
QString readLine(qint64 maxlen)
GPGProc::readln
int readln(QString &line, const bool colons=false)
Reads a line of text (excluding '\n').
Definition: gpgproc.cpp:203
KGpgSignNode.h
KGpgKeyNode::getId
virtual QString getId() const
Definition: KGpgKeyNode.cpp:113
KgpgInterface::getGpgBoolSetting
bool getGpgBoolSetting(const QString &name, const QString &configfile)
Definition: kgpginterface.cpp:93
QList::at
const T & at(int i) const
QString::simplified
QString simplified() const
KGpgUatNode
A user attribute (i.e.
Definition: KGpgUatNode.h:36
KgpgCore::Convert::toTrust
KgpgKeyTrust toTrust(const QChar &c)
Definition: convert.cpp:138
KgpgCore::KgpgKey::setEmail
void setEmail(const QString &email)
Definition: kgpgkey.cpp:198
KgpgCore::KgpgKey::setValid
void setValid(const bool valid)
Definition: kgpgkey.cpp:188
KgpgCore::KgpgKey
Definition: kgpgkey.h:236
QStringList::join
QString join(const QString &separator) const
QFile::exists
bool exists() const
QString::remove
QString & remove(int position, int n)
QFile
KgpgInterface::setGpgSetting
void setGpgSetting(const QString &name, const QString &value, const QString &url)
Definition: kgpginterface.cpp:58
KgpgCore::KgpgKey::setComment
void setComment(const QString &comment)
Definition: kgpgkey.cpp:203
QTextStream
KGpgKeyNode
A public key with or without corresponding secret key.
Definition: KGpgKeyNode.h:33
KgpgCore::KgpgKey::fingerprint
const QString & fingerprint() const
Definition: kgpgkey.cpp:258
KgpgCore::Images::signature
QPixmap signature()
Definition: images.cpp:64
QString::clear
void clear()
QDateTime::fromTime_t
QDateTime fromTime_t(uint seconds)
KgpgCore::KgpgKey::setExpiration
void setExpiration(const QDateTime &date)
Definition: kgpgkey.cpp:218
GPGProc::start
void start()
Starts the process.
Definition: gpgproc.cpp:185
KgpgCore::KgpgKeySub
Definition: kgpgkey.h:132
QTextStream::atEnd
bool atEnd() const
KgpgInterface::readSignatures
void readSignatures(KGpgKeyNode *node)
Definition: kgpginterface.cpp:305
KgpgInterface::readPublicKeys
KgpgCore::KgpgKeyList readPublicKeys(const QStringList &ids=QStringList())
Definition: kgpginterface.cpp:288
KgpgCore::KgpgKey::setOwnerTrust
void setOwnerTrust(const gpgme_validity_t owtrust)
Definition: kgpgkey.cpp:213
QString::isEmpty
bool isEmpty() const
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
gpgproc.h
KgpgCore::Convert::toSubType
KgpgSubKeyType toSubType(const QString &capString, bool upper)
parse the GnuPG capabilities field
Definition: convert.cpp:187
kgpginterface.h
KGpgSubkeyNode
a subkey of a public key or key pair
Definition: KGpgSubkeyNode.h:31
QString
QFile::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
KgpgCore::Convert::toOwnerTrust
gpgme_validity_t toOwnerTrust(const QChar &c)
Definition: convert.cpp:171
QStringList
KgpgCore::KgpgKeyList
Definition: kgpgkey.h:293
QString::contains
bool contains(QChar ch, Qt::CaseSensitivity cs) const
QLatin1Char
QFile::close
virtual void close()
KgpgInterface::readSecretKeys
KgpgCore::KgpgKeyList readSecretKeys(const QStringList &ids=QStringList())
Definition: kgpginterface.cpp:402
QString::replace
QString & replace(int position, int n, QChar after)
QString::mid
QString mid(int position, int n) const
QLatin1String
QList::last
T & last()
KGpgKeyNode.h
QString::length
int length() const
QString::section
QString section(QChar sep, int start, int end, QFlags< QString::SectionFlag > flags) const
KGpgSubkeyNode.h
KGpgUidNode
A user id of a public key or key pair.
Definition: KGpgUidNode.h:33
KGpgSignNode
A signature to another key object.
Definition: KGpgSignNode.h:31
readSecretKeysProcess
static KgpgCore::KgpgKeyList readSecretKeysProcess(GPGProc &p)
Definition: kgpginterface.cpp:324
readPublicKeysProcess
static KgpgCore::KgpgKeyList readPublicKeysProcess(GPGProc &p, KGpgKeyNode *readNode)
Definition: kgpginterface.cpp:148
convert.h
KgpgCore::KgpgKey::setSecret
void setSecret(const bool secret)
Definition: kgpgkey.cpp:183
KgpgCore::Convert::toAlgo
KgpgKeyAlgo toAlgo(const uint v)
Definition: convert.cpp:116
KGpgSignableNode
An object that may have KGpgSignNode children.
Definition: KGpgSignableNode.h:31
QDateTime
KgpgInterface::getGpgSetting
QString getGpgSetting(const QString &name, const QString &configfile)
Definition: kgpginterface.cpp:38
QString::toUInt
uint toUInt(bool *ok, int base) const
KgpgCore::KgpgKey::subList
KgpgKeySubListPtr subList() const
Definition: kgpgkey.cpp:340
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:42:08 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
  • ktimer
  • kwallet
  • 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