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

KDECore

ksslcertificatemanager.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002  *
00003  * Copyright (C) 2007, 2008 Andreas Hartmetz <ahartmetz@gmail.com>
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Library General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Library General Public License
00016  * along with this library; see the file COPYING.LIB.  If not, write to
00017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019  */
00020 
00021 
00022 #include "ksslcertificatemanager.h"
00023 #include "ktcpsocket.h"
00024 #include "ktcpsocket_p.h"
00025 #include <kconfig.h>
00026 #include <kconfiggroup.h>
00027 #include <kdebug.h>
00028 #include <kglobal.h>
00029 #include <klocale.h>
00030 #include <kstandarddirs.h>
00031 #include <ktoolinvocation.h>
00032 
00033 #include <QtDBus/QtDBus>
00034 
00035 #include "kssld/kssld_interface.h"
00036 
00037 
00038 /*
00039   Config file format:
00040 [<MD5-Digest>]
00041 <Host> = <Date> <List of ignored errors>
00042 #for example
00043 #mail.kdab.net =  ExpireUTC 2008-08-20T18:22:14, SelfSigned, Expired
00044 #very.old.com =  ExpireUTC 2008-08-20T18:22:14, TooWeakEncryption <- not actually planned to implement
00045 #clueless.admin.com =  ExpireUTC 2008-08-20T18:22:14, HostNameMismatch
00046 #
00047 #Wildcard syntax
00048 #* = ExpireUTC 2008-08-20T18:22:14, SelfSigned
00049 #*.kdab.net = ExpireUTC 2008-08-20T18:22:14, SelfSigned
00050 #mail.kdab.net = ExpireUTC 2008-08-20T18:22:14, All <- not implemented
00051 #* = ExpireUTC 9999-12-31T23:59:59, Reject  #we know that something is wrong with that certificate
00052 CertificatePEM = <PEM-encoded certificate> #host entries are all lowercase, thus no clashes
00053 
00054  */
00055 
00056 class KSslCertificateRulePrivate
00057 {
00058 public:
00059     QSslCertificate certificate;
00060     QString hostName;
00061     bool isRejected;
00062     QDateTime expiryDateTime;
00063     QList<KSslError::Error> ignoredErrors;
00064 };
00065 
00066 
00067 KSslCertificateRule::KSslCertificateRule(const QSslCertificate &cert, const QString &hostName)
00068  : d(new KSslCertificateRulePrivate())
00069 {
00070     d->certificate = cert;
00071     d->hostName = hostName;
00072     d->isRejected = false;
00073 }
00074 
00075 
00076 KSslCertificateRule::KSslCertificateRule(const KSslCertificateRule &other)
00077  : d(new KSslCertificateRulePrivate())
00078 {
00079     *d = *other.d;
00080 }
00081 
00082 
00083 KSslCertificateRule::~KSslCertificateRule()
00084 {
00085     delete d;
00086 }
00087 
00088 
00089 KSslCertificateRule &KSslCertificateRule::operator=(const KSslCertificateRule &other)
00090 {
00091     *d = *other.d;
00092     return *this;
00093 }
00094 
00095 
00096 QSslCertificate KSslCertificateRule::certificate() const
00097 {
00098     return d->certificate;
00099 }
00100 
00101 
00102 QString KSslCertificateRule::hostName() const
00103 {
00104     return d->hostName;
00105 }
00106 
00107 
00108 void KSslCertificateRule::setExpiryDateTime(const QDateTime &dateTime)
00109 {
00110     d->expiryDateTime = dateTime;
00111 }
00112 
00113 
00114 QDateTime KSslCertificateRule::expiryDateTime() const
00115 {
00116     return d->expiryDateTime;
00117 }
00118 
00119 
00120 void KSslCertificateRule::setRejected(bool rejected)
00121 {
00122     d->isRejected = rejected;
00123 }
00124 
00125 
00126 bool KSslCertificateRule::isRejected() const
00127 {
00128     return d->isRejected;
00129 }
00130 
00131 
00132 bool KSslCertificateRule::isErrorIgnored(KSslError::Error error) const
00133 {
00134     foreach (KSslError::Error ignoredError, d->ignoredErrors)
00135         if (error == ignoredError)
00136             return true;
00137 
00138     return false;
00139 }
00140 
00141 
00142 void KSslCertificateRule::setIgnoredErrors(const QList<KSslError::Error> &errors)
00143 {
00144     d->ignoredErrors.clear();
00145     //### Quadratic runtime, woohoo! Use a QSet if that should ever be an issue.
00146     foreach(KSslError::Error e, errors)
00147         if (!isErrorIgnored(e))
00148             d->ignoredErrors.append(e);
00149 }
00150 
00151 
00152 void KSslCertificateRule::setIgnoredErrors(const QList<KSslError> &errors)
00153 {
00154     QList<KSslError::Error> el;
00155     foreach(const KSslError &e, errors)
00156         el.append(e.error());
00157     setIgnoredErrors(el);
00158 }
00159 
00160 
00161 QList<KSslError::Error> KSslCertificateRule::ignoredErrors() const
00162 {
00163     return d->ignoredErrors;
00164 }
00165 
00166 
00167 QList<KSslError::Error> KSslCertificateRule::filterErrors(const QList<KSslError::Error> &errors) const
00168 {
00169     QList<KSslError::Error> ret;
00170     foreach (KSslError::Error error, errors) {
00171         if (!isErrorIgnored(error))
00172             ret.append(error);
00173     }
00174     return ret;
00175 }
00176 
00177 
00178 QList<KSslError> KSslCertificateRule::filterErrors(const QList<KSslError> &errors) const
00179 {
00180     QList<KSslError> ret;
00181     foreach (const KSslError &error, errors) {
00182         if (!isErrorIgnored(error.error()))
00183             ret.append(error);
00184     }
00185     return ret;
00186 }
00187 
00188 
00190 
00191 class KSslCertificateManagerContainer
00192 {
00193 public:
00194     KSslCertificateManager sslCertificateManager;
00195 };
00196 
00197 K_GLOBAL_STATIC(KSslCertificateManagerContainer, g_instance)
00198 
00199 
00200 class KSslCertificateManagerPrivate
00201 {
00202 public:
00203     KSslCertificateManagerPrivate()
00204      : config("ksslcertificatemanager", KConfig::SimpleConfig), //TODO really good conf filename
00205        iface("org.kde.kded", "/modules/kssld", QDBusConnection::sessionBus()),
00206        isCertListLoaded(false)
00207     {
00208         // set Qt's set to empty; this is protected by the lock in K_GLOBAL_STATIC.
00209         QSslSocket::setDefaultCaCertificates(QList<QSslCertificate>());
00210     }
00211 
00212     void loadDefaultCaCertificates()
00213     {
00214         if (isCertListLoaded) {
00215             // we've had a race between two threads trying to load the certs; don't actually
00216             // load them twice.
00217             return;
00218         }
00219         defaultCaCertificates.clear();
00220 
00221         if (!KGlobal::hasMainComponent()) {
00222             Q_ASSERT(false);
00223             return;                 // we need KGlobal::dirs() available
00224         }
00225 
00226         // set default CAs from KDE's own bundle
00227         QStringList bundles = KGlobal::dirs()->findAllResources("data", "kssl/ca-bundle.crt");
00228         foreach (const QString &bundle, bundles) {
00229             defaultCaCertificates += QSslCertificate::fromPath(bundle);
00230         }
00231         // We don't need to lock the mutex when retrieving the list without loading it first
00232         // because when the following flag is true the list is complete.
00233         isCertListLoaded = true;
00234 
00235         kDebug(7029) << "Loading" << defaultCaCertificates.count() << "CA certificates from" << bundles;
00236     }
00237 
00238     KConfig config;
00239     org::kde::KSSLDInterface iface;
00240     QHash<QString, KSslError::Error> stringToSslError;
00241     QHash<KSslError::Error, QString> sslErrorToString;
00242 
00243     QList<QSslCertificate> defaultCaCertificates;
00244     QMutex certListMutex;
00245     bool isCertListLoaded;
00246 };
00247 
00248 
00249 KSslCertificateManager::KSslCertificateManager()
00250  : d(new KSslCertificateManagerPrivate())
00251 {
00252     // Make sure kded is running
00253     if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kded")) {
00254         KToolInvocation::klauncher(); // this calls startKdeinit
00255     }
00256 }
00257 
00258 
00259 KSslCertificateManager::~KSslCertificateManager()
00260 {
00261     delete d;
00262 }
00263 
00264 
00265 //static
00266 KSslCertificateManager *KSslCertificateManager::self()
00267 {
00268     return &g_instance->sslCertificateManager;
00269 }
00270 
00271 
00272 void KSslCertificateManager::setRule(const KSslCertificateRule &rule)
00273 {
00274     d->iface.setRule(rule);
00275 }
00276 
00277 
00278 void KSslCertificateManager::clearRule(const KSslCertificateRule &rule)
00279 {
00280     d->iface.clearRule(rule);
00281 }
00282 
00283 
00284 void KSslCertificateManager::clearRule(const QSslCertificate &cert, const QString &hostName)
00285 {
00286     d->iface.clearRule(cert, hostName);
00287 }
00288 
00289 
00290 KSslCertificateRule KSslCertificateManager::rule(const QSslCertificate &cert, const QString &hostName) const
00291 {
00292     return d->iface.rule(cert, hostName);
00293 }
00294 
00295 
00296 void KSslCertificateManager::setRootCertificates(const QList<QSslCertificate> &rootCertificates)
00297 {
00298     // d->iface.setRootCertificates(rootCertificates);
00299     // TODO remove above stuff from the interface
00300 
00301     QMutexLocker certLocker(&d->certListMutex);
00302     d->defaultCaCertificates = rootCertificates;
00303     // don't do delayed initialization: the list *is* now initialized
00304     d->isCertListLoaded = true;
00305 }
00306 
00307 
00308 QList<QSslCertificate> KSslCertificateManager::rootCertificates() const
00309 {
00310     // return d->iface.rootCertificates();
00311     // TODO remove from interface, see setRootCertificates()
00312 
00313     QMutexLocker certLocker(&d->certListMutex);
00314     if (!d->isCertListLoaded) {
00315         d->loadDefaultCaCertificates();
00316     }
00317     return d->defaultCaCertificates;
00318 }
00319 
00320 //static
00321 QList<KSslError> KSslCertificateManager::nonIgnorableErrors(const QList<KSslError> &/*e*/)
00322 {
00323     QList<KSslError> ret;
00324     // ### add filtering here...
00325     return ret;
00326 }
00327 
00328 //static
00329 QList<KSslError::Error> KSslCertificateManager::nonIgnorableErrors(const QList<KSslError::Error> &/*e*/)
00330 {
00331     QList<KSslError::Error> ret;
00332     // ### add filtering here...
00333     return ret;
00334 }
00335 
00336 
00337 #include "kssld/kssld_interface.moc"

KDECore

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal