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 QDBusConnection::sessionBus().registerObject("/KdedKssl", this);
00093 }
00094
00095
00096 KSSLD::~KSSLD()
00097 {
00098 delete d;
00099 }
00100
00101
00102 void KSSLD::setRule(const KSslCertificateRule &rule)
00103 {
00104 if (rule.hostName().isEmpty()) {
00105 return;
00106 }
00107 KConfigGroup group = d->config.group(rule.certificate().digest());
00108
00109 QStringList sl;
00110
00111 QString dtString("ExpireUTC ");
00112 dtString.append(rule.expiryDateTime().toString(Qt::ISODate));
00113 sl.append(dtString);
00114
00115 if (rule.isRejected()) {
00116 sl.append("Reject");
00117 } else {
00118 foreach (KSslError::Error e, rule.ignoredErrors())
00119 sl.append(d->sslErrorToString.value(e));
00120 }
00121
00122 if (!group.hasKey("CertificatePEM"))
00123 group.writeEntry("CertificatePEM", rule.certificate().toPem());
00124 #ifdef PARANOIA
00125 else
00126 if (group.readEntry("CertificatePEM") != rule.certificate().toPem())
00127 return;
00128 #endif
00129 group.writeEntry(rule.hostName(), sl);
00130 group.sync();
00131 }
00132
00133
00134 void KSSLD::clearRule(const KSslCertificateRule &rule)
00135 {
00136 clearRule(rule.certificate(), rule.hostName());
00137 }
00138
00139
00140 void KSSLD::clearRule(const QSslCertificate &cert, const QString &hostName)
00141 {
00142 KConfigGroup group = d->config.group(cert.digest());
00143 group.deleteEntry(hostName);
00144 if (group.keyList().size() < 2) {
00145 group.deleteGroup();
00146 }
00147 group.sync();
00148 }
00149
00150
00151 KSslCertificateRule KSSLD::rule(const QSslCertificate &cert, const QString &hostName) const
00152 {
00153 KConfigGroup group = d->config.group(cert.digest());
00154
00155
00156 QString key = hostName;
00157 bool foundHostName = false;
00158 if (group.hasKey(key)) {
00159 foundHostName = true;
00160 } else {
00161 QString starDot("*.");
00162 while (!key.isEmpty()) {
00163 if (group.hasKey(starDot + key)) {
00164 foundHostName = true;
00165 break;
00166 }
00167
00168 int dotIndex = key.indexOf('.');
00169 if (dotIndex < 0)
00170 break;
00171 key.remove(0, dotIndex + 1);
00172 }
00173 key.prepend(starDot);
00174 }
00175 if (!foundHostName) {
00176
00177 return KSslCertificateRule(cert, hostName);
00178 }
00179
00180
00181 KSslCertificateRule ret(cert, key);
00182
00183 #ifdef PARANOIA
00184 if (group.readEntry("CertificatePEM") != cert.toPem())
00185 return ret;
00186 #endif
00187
00188
00189 QStringList sl = group.readEntry(key, QStringList());
00190
00191 QString dtString = sl.takeFirst();
00192 if (!dtString.startsWith("ExpireUTC "))
00193 return ret;
00194 dtString.remove(0, 10);
00195
00196 QDateTime expiryDt = QDateTime::fromString(dtString, Qt::ISODate);
00197 if (!expiryDt.isValid() || expiryDt < QDateTime::currentDateTime()) {
00198
00199 group.deleteEntry(key);
00200
00201 if (group.keyList().size() < 2)
00202 group.deleteGroup();
00203 group.sync();
00204 return ret;
00205 }
00206
00207 QList<KSslError::Error> ignoredErrors;
00208 bool isRejected = false;
00209 foreach (const QString &s, sl) {
00210 if (s == "Reject") {
00211 isRejected = true;
00212 ignoredErrors.clear();
00213 break;
00214 }
00215 if (!d->stringToSslError.contains(s))
00216 continue;
00217 ignoredErrors.append(d->stringToSslError.value(s));
00218 }
00219
00220
00221 ret.setExpiryDateTime(expiryDt);
00222 ret.setRejected(isRejected);
00223 ret.setIgnoredErrors(ignoredErrors);
00224 return ret;
00225 }
00226
00227
00228 void KSSLD::setRootCertificates(const QList<QSslCertificate> &rootCertificates)
00229 {
00230
00231 }
00232
00233
00234 QList<QSslCertificate> KSSLD::rootCertificates() const
00235 {
00236
00237 return QList<QSslCertificate>();
00238 }
00239
00240
00241 #include "kssld.moc"
00242 #include "kssld_adaptor.moc"