KDECore
kssld.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "kssld.h"
00024
00025 #include "ksslcertificatemanager.h"
00026 #include "kssld_adaptor.h"
00027
00028 #include <kconfig.h>
00029 #include <kconfiggroup.h>
00030 #include <QtCore/QFile>
00031 #include <kglobal.h>
00032 #include <kstandarddirs.h>
00033 #include <kdebug.h>
00034 #include <QtCore/QDate>
00035 #include <kpluginfactory.h>
00036 #include <kpluginloader.h>
00037
00038
00039
00040 K_PLUGIN_FACTORY(KSSLDFactory, registerPlugin<KSSLD>();)
00041 K_EXPORT_PLUGIN(KSSLDFactory("kssld"))
00042
00043
00044
00045 class KSSLDPrivate
00046 {
00047 public:
00048 KSSLDPrivate()
00049 : config("ksslcertificatemanager", KConfig::SimpleConfig)
00050 {
00051 struct strErr {
00052 const char *str;
00053 KSslError::Error err;
00054 };
00055
00056
00057 const static strErr strError[] = {
00058 {"NoError", KSslError::NoError},
00059 {"UnknownError", KSslError::UnknownError},
00060 {"InvalidCertificateAuthority", KSslError::InvalidCertificateAuthorityCertificate},
00061 {"InvalidCertificate", KSslError::InvalidCertificate},
00062 {"CertificateSignatureFailed", KSslError::CertificateSignatureFailed},
00063 {"SelfSignedCertificate", KSslError::SelfSignedCertificate},
00064 {"RevokedCertificate", KSslError::RevokedCertificate},
00065 {"InvalidCertificatePurpose", KSslError::InvalidCertificatePurpose},
00066 {"RejectedCertificate", KSslError::RejectedCertificate},
00067 {"UntrustedCertificate", KSslError::UntrustedCertificate},
00068 {"ExpiredCertificate", KSslError::ExpiredCertificate},
00069 {"HostNameMismatch", KSslError::HostNameMismatch}
00070 };
00071
00072 for (int i = 0; i < int(sizeof(strError)/sizeof(strErr)); i++) {
00073 QString s = QString::fromLatin1(strError[i].str);
00074 KSslError::Error e = strError[i].err;
00075 stringToSslError.insert(s, e);
00076 sslErrorToString.insert(e, s);
00077 }
00078 }
00079
00080 KConfig config;
00081 QHash<QString, KSslError::Error> stringToSslError;
00082 QHash<KSslError::Error, QString> sslErrorToString;
00083 };
00084
00085
00086
00087 KSSLD::KSSLD(QObject* parent, const QVariantList&)
00088 : KDEDModule(parent),
00089 d(new KSSLDPrivate())
00090 {
00091 new KSSLDAdaptor(this);
00092 }
00093
00094
00095 KSSLD::~KSSLD()
00096 {
00097 delete d;
00098 }
00099
00100
00101 void KSSLD::setRule(const KSslCertificateRule &rule)
00102 {
00103 if (rule.hostName().isEmpty()) {
00104 return;
00105 }
00106 KConfigGroup group = d->config.group(rule.certificate().digest().toHex());
00107
00108 QStringList sl;
00109
00110 QString dtString("ExpireUTC ");
00111 dtString.append(rule.expiryDateTime().toString(Qt::ISODate));
00112 sl.append(dtString);
00113
00114 if (rule.isRejected()) {
00115 sl.append("Reject");
00116 } else {
00117 foreach (KSslError::Error e, rule.ignoredErrors())
00118 sl.append(d->sslErrorToString.value(e));
00119 }
00120
00121 if (!group.hasKey("CertificatePEM"))
00122 group.writeEntry("CertificatePEM", rule.certificate().toPem());
00123 #ifdef PARANOIA
00124 else
00125 if (group.readEntry("CertificatePEM") != rule.certificate().toPem())
00126 return;
00127 #endif
00128 group.writeEntry(rule.hostName(), sl);
00129 group.sync();
00130 }
00131
00132
00133 void KSSLD::clearRule(const KSslCertificateRule &rule)
00134 {
00135 clearRule(rule.certificate(), rule.hostName());
00136 }
00137
00138
00139 void KSSLD::clearRule(const QSslCertificate &cert, const QString &hostName)
00140 {
00141 KConfigGroup group = d->config.group(cert.digest().toHex());
00142 group.deleteEntry(hostName);
00143 if (group.keyList().size() < 2) {
00144 group.deleteGroup();
00145 }
00146 group.sync();
00147 }
00148
00149
00150 KSslCertificateRule KSSLD::rule(const QSslCertificate &cert, const QString &hostName) const
00151 {
00152 KConfigGroup group = d->config.group(cert.digest().toHex());
00153
00154
00155 QString key = hostName;
00156 bool foundHostName = false;
00157 if (group.hasKey(key)) {
00158 foundHostName = true;
00159 } else {
00160 QString starDot("*.");
00161 while (!key.isEmpty()) {
00162 if (group.hasKey(starDot + key)) {
00163 foundHostName = true;
00164 break;
00165 }
00166
00167 int dotIndex = key.indexOf('.');
00168 if (dotIndex < 0)
00169 break;
00170 key.remove(0, dotIndex + 1);
00171 }
00172 key.prepend(starDot);
00173 }
00174 if (!foundHostName) {
00175
00176 return KSslCertificateRule(cert, hostName);
00177 }
00178
00179
00180 KSslCertificateRule ret(cert, key);
00181
00182 #ifdef PARANOIA
00183 if (group.readEntry("CertificatePEM") != cert.toPem())
00184 return ret;
00185 #endif
00186
00187
00188 QStringList sl = group.readEntry(key, QStringList());
00189
00190 QString dtString = sl.takeFirst();
00191 if (!dtString.startsWith("ExpireUTC "))
00192 return ret;
00193 dtString.remove(0, 10);
00194
00195 QDateTime expiryDt = QDateTime::fromString(dtString, Qt::ISODate);
00196 if (!expiryDt.isValid() || expiryDt < QDateTime::currentDateTime()) {
00197
00198 group.deleteEntry(key);
00199
00200 if (group.keyList().size() < 2)
00201 group.deleteGroup();
00202 group.sync();
00203 return ret;
00204 }
00205
00206 QList<KSslError::Error> ignoredErrors;
00207 bool isRejected = false;
00208 foreach (const QString &s, sl) {
00209 if (s == "Reject") {
00210 isRejected = true;
00211 ignoredErrors.clear();
00212 break;
00213 }
00214 if (!d->stringToSslError.contains(s))
00215 continue;
00216 ignoredErrors.append(d->stringToSslError.value(s));
00217 }
00218
00219
00220 ret.setExpiryDateTime(expiryDt);
00221 ret.setRejected(isRejected);
00222 ret.setIgnoredErrors(ignoredErrors);
00223 return ret;
00224 }
00225
00226
00227 void KSSLD::setRootCertificates(const QList<QSslCertificate> &rootCertificates)
00228 {
00229
00230 }
00231
00232
00233 QList<QSslCertificate> KSSLD::rootCertificates() const
00234 {
00235
00236 return QList<QSslCertificate>();
00237 }
00238
00239
00240 #include "kssld.moc"
00241 #include "kssld_adaptor.moc"