📄 kssld.cpp
字号:
/* This file is part of the KDE libraries Copyright (c) 2001-2005 George Staikos <staikos@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <qtimer.h>#include "kssld.h"#include <kconfig.h>#include <ksimpleconfig.h>#include <ksslcertchain.h>#include <ksslcertificate.h>#include <ksslcertificatehome.h>#include <ksslpkcs12.h>#include <ksslx509map.h>#include <qptrlist.h>#include <sys/types.h>#include <sys/stat.h>#include <stdlib.h>#include <pwd.h>#include <unistd.h>#include <qfile.h>#include <qsortedlist.h>#include <kglobal.h>#include <kstandarddirs.h>#include <kdebug.h>#include <qdatetime.h>#include <kmdcodec.h>#include <kopenssl.h>// See design notes at endextern "C" { KDE_EXPORT KDEDModule *create_kssld(const QCString &name) { return new KSSLD(name); } KDE_EXPORT void *__kde_do_unload;}static void updatePoliciesConfig(KConfig *cfg) { QStringList groups = cfg->groupList(); for (QStringList::Iterator i = groups.begin(); i != groups.end(); ++i) { if ((*i).isEmpty() || *i == "General") { continue; } cfg->setGroup(*i); // remove it if it has expired if (!cfg->readBoolEntry("Permanent") && cfg->readDateTimeEntry("Expires") < QDateTime::currentDateTime()) { cfg->deleteGroup(*i); continue; } QString encodedCertStr = cfg->readEntry("Certificate"); QCString encodedCert = encodedCertStr.local8Bit(); KSSLCertificate *newCert = KSSLCertificate::fromString(encodedCert); if (!newCert) { cfg->deleteGroup(*i); continue; } KSSLCertificateCache::KSSLCertificatePolicy policy = (KSSLCertificateCache::KSSLCertificatePolicy) cfg->readNumEntry("Policy"); bool permanent = cfg->readBoolEntry("Permanent"); QDateTime expires = cfg->readDateTimeEntry("Expires"); QStringList hosts = cfg->readListEntry("Hosts"); QStringList chain = cfg->readListEntry("Chain"); cfg->deleteGroup(*i); cfg->setGroup(newCert->getMD5Digest()); cfg->writeEntry("Certificate", encodedCertStr); cfg->writeEntry("Policy", policy); cfg->writeEntry("Permanent", permanent); cfg->writeEntry("Expires", expires); cfg->writeEntry("Hosts", hosts); cfg->writeEntry("Chain", chain); delete newCert; } cfg->setGroup("General"); cfg->writeEntry("policies version", 2); cfg->sync();}KSSLD::KSSLD(const QCString &name) : KDEDModule(name){// ----------------------- FOR THE CACHE ------------------------------------ cfg = new KSimpleConfig("ksslpolicies", false); cfg->setGroup("General"); if (2 != cfg->readNumEntry("policies version", 0)) { ::updatePoliciesConfig(cfg); } KGlobal::dirs()->addResourceType("kssl", KStandardDirs::kde_default("data") + "kssl"); caVerifyUpdate(); cacheLoadDefaultPolicies(); certList.setAutoDelete(false); kossl = KOSSL::self();// ----------------------- FOR THE HOME -------------------------------------} KSSLD::~KSSLD(){// ----------------------- FOR THE CACHE ------------------------------------ cacheClearList(); delete cfg;// ----------------------- FOR THE HOME -------------------------------------} // A node in the cacheclass KSSLCNode { public: KSSLCertificate *cert; KSSLCertificateCache::KSSLCertificatePolicy policy; bool permanent; QDateTime expires; QStringList hosts; KSSLCNode() { cert = 0L; policy = KSSLCertificateCache::Unknown; permanent = true; } ~KSSLCNode() { delete cert; }};void KSSLD::cacheSaveToDisk() {KSSLCNode *node; cfg->setGroup("General"); cfg->writeEntry("policies version", 2); for (node = certList.first(); node; node = certList.next()) { if (node->permanent || node->expires > QDateTime::currentDateTime()) { // First convert to a binary format and then write the // kconfig entry write the (CN, policy, cert) to // KSimpleConfig cfg->setGroup(node->cert->getMD5Digest()); cfg->writeEntry("Certificate", node->cert->toString()); cfg->writeEntry("Policy", node->policy); cfg->writeEntry("Expires", node->expires); cfg->writeEntry("Permanent", node->permanent); cfg->writeEntry("Hosts", node->hosts); // Also write the chain QStringList qsl; QPtrList<KSSLCertificate> cl = node->cert->chain().getChain(); for (KSSLCertificate *c = cl.first(); c != 0; c = cl.next()) { //kdDebug() << "Certificate in chain: " // << c->toString() << endl; qsl << c->toString(); } cl.setAutoDelete(true); cfg->writeEntry("Chain", qsl); } } cfg->sync(); // insure proper permissions -- contains sensitive data QString cfgName(KGlobal::dirs()->findResource("config", "ksslpolicies")); if (!cfgName.isEmpty()) { ::chmod(QFile::encodeName(cfgName), 0600); }}void KSSLD::cacheReload() { cacheClearList(); delete cfg; cfg = new KSimpleConfig("ksslpolicies", false); cacheLoadDefaultPolicies();}void KSSLD::cacheClearList() {KSSLCNode *node; for (node = certList.first(); node; node = certList.next()) { certList.remove(node); delete node; } skEmail.clear(); skMD5Digest.clear();}void KSSLD::cacheLoadDefaultPolicies() {QStringList groups = cfg->groupList(); for (QStringList::Iterator i = groups.begin(); i != groups.end(); ++i) { if ((*i).isEmpty() || *i == "General") { continue; } cfg->setGroup(*i); // remove it if it has expired if (!cfg->readBoolEntry("Permanent") && cfg->readDateTimeEntry("Expires") < QDateTime::currentDateTime()) { cfg->deleteGroup(*i); continue; } QCString encodedCert; KSSLCertificate *newCert; encodedCert = cfg->readEntry("Certificate").local8Bit(); newCert = KSSLCertificate::fromString(encodedCert); if (!newCert) { continue; } KSSLCNode *n = new KSSLCNode; n->cert = newCert; n->policy = (KSSLCertificateCache::KSSLCertificatePolicy) cfg->readNumEntry("Policy"); n->permanent = cfg->readBoolEntry("Permanent"); n->expires = cfg->readDateTimeEntry("Expires"); n->hosts = cfg->readListEntry("Hosts"); newCert->chain().setCertChain(cfg->readListEntry("Chain")); certList.append(n); searchAddCert(newCert); }}void KSSLD::cacheAddCertificate(KSSLCertificate cert, KSSLCertificateCache::KSSLCertificatePolicy policy, bool permanent) {KSSLCNode *node; for (node = certList.first(); node; node = certList.next()) { if (cert == *(node->cert)) { node->policy = policy; node->permanent = permanent; if (!permanent) { node->expires = QDateTime::currentDateTime(); // FIXME: make this configurable node->expires = node->expires.addSecs(3600); } cacheSaveToDisk(); return; } } KSSLCNode *n = new KSSLCNode; n->cert = cert.replicate(); n->policy = policy; n->permanent = permanent; // remove the old one cacheRemoveByCertificate(*(n->cert)); certList.prepend(n); if (!permanent) { n->expires = QDateTime::currentDateTime(); n->expires = n->expires.addSecs(3600); } searchAddCert(n->cert); cacheSaveToDisk();}KSSLCertificateCache::KSSLCertificatePolicy KSSLD::cacheGetPolicyByCN(QString cn) {KSSLCNode *node; for (node = certList.first(); node; node = certList.next()) { if (KSSLX509Map(node->cert->getSubject()).getValue("CN") == cn) { if (!node->permanent && node->expires < QDateTime::currentDateTime()) { certList.remove(node); cfg->deleteGroup(node->cert->getMD5Digest()); delete node; continue; } certList.remove(node); certList.prepend(node); cacheSaveToDisk(); return node->policy; } } cacheSaveToDisk();return KSSLCertificateCache::Unknown;}KSSLCertificateCache::KSSLCertificatePolicy KSSLD::cacheGetPolicyByCertificate(KSSLCertificate cert) {KSSLCNode *node; for (node = certList.first(); node; node = certList.next()) { if (cert == *(node->cert)) { if (!node->permanent && node->expires < QDateTime::currentDateTime()) { certList.remove(node); cfg->deleteGroup(node->cert->getMD5Digest()); delete node; cacheSaveToDisk(); return KSSLCertificateCache::Unknown; } certList.remove(node); certList.prepend(node); return node->policy; } }return KSSLCertificateCache::Unknown;}bool KSSLD::cacheSeenCN(QString cn) {KSSLCNode *node; for (node = certList.first(); node; node = certList.next()) { if (KSSLX509Map(node->cert->getSubject()).getValue("CN") == cn) { if (!node->permanent && node->expires < QDateTime::currentDateTime()) { certList.remove(node); cfg->deleteGroup(node->cert->getMD5Digest()); delete node; cacheSaveToDisk(); continue; } certList.remove(node); certList.prepend(node); return true; } }return false;}bool KSSLD::cacheSeenCertificate(KSSLCertificate cert) {KSSLCNode *node; for (node = certList.first(); node; node = certList.next()) { if (cert == *(node->cert)) { if (!node->permanent && node->expires < QDateTime::currentDateTime()) { certList.remove(node); cfg->deleteGroup(node->cert->getMD5Digest()); delete node; cacheSaveToDisk(); return false; } certList.remove(node); certList.prepend(node); return true; } }return false;}bool KSSLD::cacheIsPermanent(KSSLCertificate cert) {KSSLCNode *node; for (node = certList.first(); node; node = certList.next()) { if (cert == *(node->cert)) { if (!node->permanent && node->expires < QDateTime::currentDateTime()) { certList.remove(node); cfg->deleteGroup(node->cert->getMD5Digest()); delete node; cacheSaveToDisk(); return false; } certList.remove(node); certList.prepend(node); return node->permanent; } }return false;}bool KSSLD::cacheRemoveBySubject(QString subject) {KSSLCNode *node;bool gotOne = false; for (node = certList.first(); node; node = certList.next()) { if (node->cert->getSubject() == subject) { certList.remove(node); cfg->deleteGroup(node->cert->getMD5Digest()); searchRemoveCert(node->cert); delete node; gotOne = true; } } cacheSaveToDisk();return gotOne;}bool KSSLD::cacheRemoveByCN(QString cn) {KSSLCNode *node;bool gotOne = false; for (node = certList.first(); node; node = certList.next()) { if (KSSLX509Map(node->cert->getSubject()).getValue("CN") == cn) { certList.remove(node); cfg->deleteGroup(node->cert->getMD5Digest()); searchRemoveCert(node->cert); delete node; gotOne = true; } } cacheSaveToDisk();return gotOne;}bool KSSLD::cacheRemoveByCertificate(KSSLCertificate cert) {KSSLCNode *node; for (node = certList.first(); node; node = certList.next()) { if (cert == *(node->cert)) { certList.remove(node); cfg->deleteGroup(node->cert->getMD5Digest()); searchRemoveCert(node->cert); delete node; cacheSaveToDisk(); return true; } }return false;}bool KSSLD::cacheModifyByCN(QString cn, KSSLCertificateCache::KSSLCertificatePolicy policy, bool permanent, QDateTime expires) {KSSLCNode *node; for (node = certList.first(); node; node = certList.next()) { if (KSSLX509Map(node->cert->getSubject()).getValue("CN") == cn) { node->permanent = permanent; node->expires = expires; node->policy = policy; certList.remove(node); certList.prepend(node); cacheSaveToDisk(); return true; } }return false;}bool KSSLD::cacheModifyByCertificate(KSSLCertificate cert, KSSLCertificateCache::KSSLCertificatePolicy policy, bool permanent, QDateTime expires) {KSSLCNode *node;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -