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

KDECore

  • sources
  • kde-4.14
  • kdelibs
  • kdecore
  • network
  • kssld
kssld.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the KDE libraries
3 
4  Copyright (c) 2007, 2008, 2010 Andreas Hartmetz <ahartmetz@gmail.com>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 
21 */
22 
23 #include "kssld.h"
24 
25 #include "ksslcertificatemanager.h"
26 #include "kssld_adaptor.h"
27 
28 #include <kconfig.h>
29 #include <kconfiggroup.h>
30 #include <QtCore/QFile>
31 #include <kglobal.h>
32 #include <kstandarddirs.h>
33 #include <kdebug.h>
34 #include <QtCore/QDate>
35 #include <kpluginfactory.h>
36 #include <kpluginloader.h>
37 
38 
39 
40 K_PLUGIN_FACTORY(KSSLDFactory, registerPlugin<KSSLD>();)
41 K_EXPORT_PLUGIN(KSSLDFactory("kssld"))
42 //KDE_EXPORT void *__kde_do_unload; // TODO re-add support for this?
43 
44 
45 class KSSLDPrivate
46 {
47 public:
48  KSSLDPrivate()
49  : config(QString::fromLatin1("ksslcertificatemanager"), KConfig::SimpleConfig)
50  {
51  struct strErr {
52  const char *str;
53  KSslError::Error err;
54  };
55 
56  //hmmm, looks like these are all of the errors where it is possible to continue.
57  const static strErr strError[] = {
58  {"NoError", KSslError::NoError},
59  {"UnknownError", KSslError::UnknownError},
60  {"InvalidCertificateAuthority", KSslError::InvalidCertificateAuthorityCertificate},
61  {"InvalidCertificate", KSslError::InvalidCertificate},
62  {"CertificateSignatureFailed", KSslError::CertificateSignatureFailed},
63  {"SelfSignedCertificate", KSslError::SelfSignedCertificate},
64  {"RevokedCertificate", KSslError::RevokedCertificate},
65  {"InvalidCertificatePurpose", KSslError::InvalidCertificatePurpose},
66  {"RejectedCertificate", KSslError::RejectedCertificate},
67  {"UntrustedCertificate", KSslError::UntrustedCertificate},
68  {"ExpiredCertificate", KSslError::ExpiredCertificate},
69  {"HostNameMismatch", KSslError::HostNameMismatch}
70  };
71 
72  for (int i = 0; i < int(sizeof(strError)/sizeof(strErr)); i++) {
73  QString s = QString::fromLatin1(strError[i].str);
74  KSslError::Error e = strError[i].err;
75  stringToSslError.insert(s, e);
76  sslErrorToString.insert(e, s);
77  }
78  }
79 
80  KConfig config;
81  QHash<QString, KSslError::Error> stringToSslError;
82  QHash<KSslError::Error, QString> sslErrorToString;
83 };
84 
85 
86 
87 KSSLD::KSSLD(QObject* parent, const QVariantList&)
88  : KDEDModule(parent),
89  d(new KSSLDPrivate())
90 {
91  new KSSLDAdaptor(this);
92  pruneExpiredRules();
93 }
94 
95 
96 KSSLD::~KSSLD()
97 {
98  delete d;
99 }
100 
101 
102 void KSSLD::setRule(const KSslCertificateRule &rule)
103 {
104  if (rule.hostName().isEmpty()) {
105  return;
106  }
107  KConfigGroup group = d->config.group(rule.certificate().digest().toHex());
108 
109  QStringList sl;
110 
111  QString dtString = QString::fromLatin1("ExpireUTC ");
112  dtString.append(rule.expiryDateTime().toString(Qt::ISODate));
113  sl.append(dtString);
114 
115  if (rule.isRejected()) {
116  sl.append(QString::fromLatin1("Reject"));
117  } else {
118  foreach (KSslError::Error e, rule.ignoredErrors())
119  sl.append(d->sslErrorToString.value(e));
120  }
121 
122  if (!group.hasKey("CertificatePEM"))
123  group.writeEntry("CertificatePEM", rule.certificate().toPem());
124 #ifdef PARANOIA
125  else
126  if (group.readEntry("CertificatePEM") != rule.certificate().toPem())
127  return;
128 #endif
129  group.writeEntry(rule.hostName(), sl);
130  group.sync();
131 }
132 
133 
134 void KSSLD::clearRule(const KSslCertificateRule &rule)
135 {
136  clearRule(rule.certificate(), rule.hostName());
137 }
138 
139 
140 void KSSLD::clearRule(const QSslCertificate &cert, const QString &hostName)
141 {
142  KConfigGroup group = d->config.group(cert.digest().toHex());
143  group.deleteEntry(hostName);
144  if (group.keyList().size() < 2) {
145  group.deleteGroup();
146  }
147  group.sync();
148 }
149 
150 
151 void KSSLD::pruneExpiredRules()
152 {
153  // expired rules are deleted when trying to load them, so we just try to load all rules.
154  // be careful about iterating over KConfig(Group) while changing it
155  foreach (const QString &groupName, d->config.groupList()) {
156  QByteArray certDigest = groupName.toLatin1();
157  foreach (const QString &key, d->config.group(groupName).keyList()) {
158  if (key == QLatin1String("CertificatePEM")) {
159  continue;
160  }
161  KSslCertificateRule r = rule(certDigest, key);
162  }
163  }
164 }
165 
166 
167 // check a domain name with subdomains for well-formedness and count the dot-separated parts
168 static QString normalizeSubdomains(const QString &hostName, int *namePartsCount)
169 {
170  QString ret;
171  int partsCount = 0;
172  bool wasPrevDot = true; // -> allow no dot at the beginning and count first name part
173  const int length = hostName.length();
174  for (int i = 0; i < length; i++) {
175  const QChar c = hostName.at(i);
176  if (c == QLatin1Char('.')) {
177  if (wasPrevDot || (i + 1 == hostName.length())) {
178  // consecutive dots or a dot at the end are forbidden
179  partsCount = 0;
180  ret.clear();
181  break;
182  }
183  wasPrevDot = true;
184  } else {
185  if (wasPrevDot) {
186  partsCount++;
187  }
188  wasPrevDot = false;
189  }
190  ret.append(c);
191  }
192 
193  *namePartsCount = partsCount;
194  return ret;
195 }
196 
197 
198 KSslCertificateRule KSSLD::rule(const QSslCertificate &cert, const QString &hostName) const
199 {
200  const QByteArray certDigest = cert.digest().toHex();
201  KConfigGroup group = d->config.group(certDigest);
202 
203  KSslCertificateRule ret(cert, hostName);
204  bool foundHostName = false;
205 
206  int needlePartsCount;
207  QString needle = normalizeSubdomains(hostName, &needlePartsCount);
208 
209  // Find a rule for the hostname, either...
210  if (group.hasKey(needle)) {
211  // directly (host, site.tld, a.site.tld etc)
212  if (needlePartsCount >= 1) {
213  foundHostName = true;
214  }
215  } else {
216  // or with wildcards
217  // "tld" <- "*." and "site.tld" <- "*.tld" are not valid matches,
218  // "a.site.tld" <- "*.site.tld" is
219  while (--needlePartsCount >= 2) {
220  const int dotIndex = needle.indexOf(QLatin1Char('.'));
221  Q_ASSERT(dotIndex > 0); // if this fails normalizeSubdomains() failed
222  needle.remove(0, dotIndex - 1);
223  needle[0] = QChar::fromLatin1('*');
224  if (group.hasKey(needle)) {
225  foundHostName = true;
226  break;
227  }
228  needle.remove(0, 2); // remove "*."
229  }
230  }
231 
232  if (!foundHostName) {
233  //Don't make a rule with the failed wildcard pattern - use the original hostname.
234  return KSslCertificateRule(cert, hostName);
235  }
236 
237  //parse entry of the format "ExpireUTC <date>, Reject" or
238  //"ExpireUTC <date>, HostNameMismatch, ExpiredCertificate, ..."
239  QStringList sl = group.readEntry(needle, QStringList());
240 
241  QDateTime expiryDt;
242  // the rule is well-formed if it contains at least the expire date and one directive
243  if (sl.size() >= 2) {
244  QString dtString = sl.takeFirst();
245  if (dtString.startsWith(QLatin1String("ExpireUTC "))) {
246  dtString.remove(0, 10/* length of "ExpireUTC " */);
247  expiryDt = QDateTime::fromString(dtString, Qt::ISODate);
248  }
249  }
250 
251  if (!expiryDt.isValid() || expiryDt < QDateTime::currentDateTime()) {
252  //the entry is malformed or expired so we remove it
253  group.deleteEntry(needle);
254  //the group is useless once only the CertificatePEM entry left
255  if (group.keyList().size() < 2) {
256  group.deleteGroup();
257  }
258  return ret;
259  }
260 
261  QList<KSslError::Error> ignoredErrors;
262  bool isRejected = false;
263  foreach (const QString &s, sl) {
264  if (s == QLatin1String("Reject")) {
265  isRejected = true;
266  ignoredErrors.clear();
267  break;
268  }
269  if (!d->stringToSslError.contains(s)) {
270  continue;
271  }
272  ignoredErrors.append(d->stringToSslError.value(s));
273  }
274 
275  //Everything is checked and we can make ret valid
276  ret.setExpiryDateTime(expiryDt);
277  ret.setRejected(isRejected);
278  ret.setIgnoredErrors(ignoredErrors);
279  return ret;
280 }
281 
282 
283 #include "kssld.moc"
284 #include "kssld_adaptor.moc"
QList::clear
void clear()
KSslCertificateRule::isRejected
bool isRejected() const
Definition: ksslcertificatemanager.cpp:128
KSslCertificateRule::certificate
QSslCertificate certificate() const
Definition: ksslcertificatemanager.cpp:98
KSslError::RejectedCertificate
Definition: ktcpsocket.h:111
QDateTime::toString
QString toString(Qt::DateFormat format) const
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
KSSLD::~KSSLD
~KSSLD()
Definition: kssld.cpp:96
QString::append
QString & append(QChar ch)
kdebug.h
QByteArray::toHex
QByteArray toHex() const
QByteArray
KMacroExpander::group
Definition: kmacroexpander_unix.cpp:34
KSslError::InvalidCertificate
Definition: ktcpsocket.h:105
KDEDModule
The base class for KDED modules.
Definition: kdedmodule.h:47
KSslError::InvalidCertificateAuthorityCertificate
Definition: ktcpsocket.h:104
KSslError::SelfSignedCertificate
Definition: ktcpsocket.h:107
QChar
kconfig.h
KConfigGroup::writeEntry
void writeEntry(const QString &key, const QVariant &value, WriteConfigFlags pFlags=Normal)
Writes a value to the configuration object.
Definition: kconfiggroup.cpp:1037
KSslCertificateRule::ignoredErrors
QList< KSslError::Error > ignoredErrors() const
Definition: ksslcertificatemanager.cpp:163
KSslError::Error
Error
Definition: ktcpsocket.h:101
kssld_adaptor.h
KSslCertificateRule::setIgnoredErrors
void setIgnoredErrors(const QList< KSslError::Error > &errors)
Definition: ksslcertificatemanager.cpp:144
QString::remove
QString & remove(int position, int n)
KConfigGroup::deleteGroup
void deleteGroup(WriteConfigFlags pFlags=Normal)
Delete all entries in the entire group.
Definition: kconfiggroup.cpp:555
ksslcertificatemanager.h
QList::size
int size() const
KGlobal::config
KSharedConfigPtr config()
Returns the general config object.
Definition: kglobal.cpp:139
KPluginFactory::K_PLUGIN_FACTORY
#define K_PLUGIN_FACTORY(name, pluginRegistrations)
Definition: kpluginfactory.h:127
QString::clear
void clear()
KConfigGroup::deleteEntry
void deleteEntry(const QString &pKey, WriteConfigFlags pFlags=Normal)
Deletes the entry specified by pKey in the current group.
Definition: kconfiggroup.cpp:1112
KSslError::HostNameMismatch
Definition: ktcpsocket.h:114
kglobal.h
QList::append
void append(const T &value)
QHash< QString, KSslError::Error >
KSslError::CertificateSignatureFailed
Definition: ktcpsocket.h:106
kssld.h
QObject
QChar::fromLatin1
QChar fromLatin1(char c)
KSslError::NoError
Definition: ktcpsocket.h:102
kpluginloader.h
QString::isEmpty
bool isEmpty() const
KSslCertificateRule::setExpiryDateTime
void setExpiryDateTime(const QDateTime &dateTime)
Definition: ksslcertificatemanager.cpp:110
KSslError::ExpiredCertificate
Definition: ktcpsocket.h:108
KSslCertificateRule::expiryDateTime
QDateTime expiryDateTime() const
Definition: ksslcertificatemanager.cpp:116
KSSLD::pruneExpiredRules
void pruneExpiredRules()
Definition: kssld.cpp:151
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
QSslCertificate::toPem
QByteArray toPem() const
QString
KSSLDAdaptor
Definition: kssld_adaptor.h:33
QList< KSslError::Error >
KSslError::UntrustedCertificate
Definition: ktcpsocket.h:112
QStringList
KConfigGroup::keyList
QStringList keyList() const
Returns a list of keys this group contains.
Definition: kconfiggroup.cpp:1174
KSslCertificateRule
Definition: ksslcertificatemanager.h:37
QLatin1Char
QDateTime::fromString
QDateTime fromString(const QString &string, Qt::DateFormat format)
QSslCertificate::digest
QByteArray digest(QCryptographicHash::Algorithm algorithm) const
KConfigGroup::hasKey
bool hasKey(const QString &key) const
Checks whether the key has an entry in this group.
Definition: kconfiggroup.cpp:1155
QDateTime::isValid
bool isValid() const
KConfigGroup
A class for one specific group in a KConfig object.
Definition: kconfiggroup.h:53
KConfig
The central class of the KDE configuration data system.
Definition: kconfig.h:70
QDateTime::currentDateTime
QDateTime currentDateTime()
QString::toLatin1
QByteArray toLatin1() const
KSslError::UnknownError
Definition: ktcpsocket.h:103
KSslCertificateRule::setRejected
void setRejected(bool rejected)
Definition: ksslcertificatemanager.cpp:122
QList::takeFirst
T takeFirst()
QLatin1String
kstandarddirs.h
kpluginfactory.h
QString::at
const QChar at(int position) const
QString::length
int length() const
QString::fromLatin1
QString fromLatin1(const char *str, int size)
KSslError::InvalidCertificatePurpose
Definition: ktcpsocket.h:110
KSslCertificateRule::hostName
QString hostName() const
Definition: ksslcertificatemanager.cpp:104
KSSLD::clearRule
void clearRule(const KSslCertificateRule &rule)
Definition: kssld.cpp:134
KConfigGroup::sync
void sync()
Definition: kconfiggroup.cpp:595
KSslError::RevokedCertificate
Definition: ktcpsocket.h:109
KSSLD::KSSLD
KSSLD(QObject *parent, const QVariantList &)
Definition: kssld.cpp:87
normalizeSubdomains
static QString normalizeSubdomains(const QString &hostName, int *namePartsCount)
Definition: kssld.cpp:168
KConfigGroup::readEntry
T readEntry(const QString &key, const T &aDefault) const
Reads the value of an entry specified by pKey in the current group.
Definition: kconfiggroup.h:248
kconfiggroup.h
QDateTime
KSSLD::setRule
void setRule(const KSslCertificateRule &rule)
Definition: kssld.cpp:102
KPluginLoader::K_EXPORT_PLUGIN
#define K_EXPORT_PLUGIN(factory)
Definition: kexportplugin.h:71
KSSLD::rule
KSslCertificateRule rule(const QSslCertificate &cert, const QString &hostName) const
Definition: kssld.cpp:198
QSslCertificate
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:22:11 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

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

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

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