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

kio

kssld.cpp

Go to the documentation of this file.
00001 /*
00002    This file is part of the KDE libraries
00003 
00004    Copyright (c) 2001-2005 George Staikos <staikos@kde.org>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019    Boston, MA 02110-1301, USA.
00020 
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 
00027 #include <qtimer.h>
00028 
00029 #include "kssld.h"
00030 #include <kconfig.h>
00031 #include <ksimpleconfig.h>
00032 #include <ksslcertchain.h>
00033 #include <ksslcertificate.h>
00034 #include <ksslcertificatehome.h>
00035 #include <ksslpkcs12.h>
00036 #include <ksslx509map.h>
00037 #include <qptrlist.h>
00038 #include <sys/types.h>
00039 #include <sys/stat.h>
00040 #include <stdlib.h>
00041 #include <pwd.h>
00042 #include <unistd.h>
00043 #include <qfile.h>
00044 #include <qsortedlist.h>
00045 #include <kglobal.h>
00046 #include <kstandarddirs.h>
00047 #include <kdebug.h>
00048 #include <qdatetime.h>
00049 
00050 #include <kmdcodec.h>
00051 #include <kopenssl.h>
00052 
00053 // See design notes at end
00054 
00055 extern "C" {
00056     KDE_EXPORT KDEDModule *create_kssld(const QCString &name) {
00057         return new KSSLD(name);
00058     }
00059 
00060     KDE_EXPORT void *__kde_do_unload;
00061 }
00062 
00063 
00064 static void updatePoliciesConfig(KConfig *cfg) {
00065     QStringList groups = cfg->groupList();
00066 
00067     for (QStringList::Iterator i = groups.begin(); i != groups.end(); ++i) {
00068         if ((*i).isEmpty() || *i == "General") {
00069             continue;
00070         }
00071 
00072         cfg->setGroup(*i);
00073 
00074         // remove it if it has expired
00075         if (!cfg->readBoolEntry("Permanent") && cfg->readDateTimeEntry("Expires") < QDateTime::currentDateTime()) {
00076             cfg->deleteGroup(*i);
00077             continue;
00078         }
00079 
00080         QString encodedCertStr = cfg->readEntry("Certificate");
00081         QCString encodedCert = encodedCertStr.local8Bit();
00082             KSSLCertificate *newCert = KSSLCertificate::fromString(encodedCert);
00083         if (!newCert) {
00084             cfg->deleteGroup(*i);
00085             continue;
00086         }
00087 
00088         KSSLCertificateCache::KSSLCertificatePolicy policy = (KSSLCertificateCache::KSSLCertificatePolicy) cfg->readNumEntry("Policy");
00089         bool permanent = cfg->readBoolEntry("Permanent");
00090         QDateTime expires = cfg->readDateTimeEntry("Expires");
00091         QStringList hosts = cfg->readListEntry("Hosts");
00092         QStringList chain = cfg->readListEntry("Chain");
00093         cfg->deleteGroup(*i);
00094 
00095         cfg->setGroup(newCert->getMD5Digest());
00096         cfg->writeEntry("Certificate", encodedCertStr);
00097         cfg->writeEntry("Policy", policy);
00098         cfg->writeEntry("Permanent", permanent);
00099         cfg->writeEntry("Expires", expires);
00100         cfg->writeEntry("Hosts", hosts);
00101         cfg->writeEntry("Chain", chain);
00102         delete newCert;
00103     }
00104 
00105     cfg->setGroup("General");
00106     cfg->writeEntry("policies version", 2);
00107 
00108     cfg->sync();
00109 }
00110 
00111 
00112 KSSLD::KSSLD(const QCString &name) : KDEDModule(name)
00113 {
00114 // ----------------------- FOR THE CACHE ------------------------------------   
00115     cfg = new KSimpleConfig("ksslpolicies", false);
00116     cfg->setGroup("General");
00117     if (2 != cfg->readNumEntry("policies version", 0)) {
00118 		::updatePoliciesConfig(cfg);
00119     }
00120     KGlobal::dirs()->addResourceType("kssl", KStandardDirs::kde_default("data") + "kssl");
00121     caVerifyUpdate();
00122     cacheLoadDefaultPolicies();
00123     certList.setAutoDelete(false);
00124     kossl = KOSSL::self();
00125 
00126 // ----------------------- FOR THE HOME -------------------------------------
00127 }
00128   
00129 
00130 KSSLD::~KSSLD()
00131 {
00132 // ----------------------- FOR THE CACHE ------------------------------------   
00133     cacheClearList();
00134     delete cfg;
00135 
00136 // ----------------------- FOR THE HOME -------------------------------------
00137 }
00138 
00139   
00140 
00141 
00142 // A node in the cache
00143 class KSSLCNode {
00144     public:
00145         KSSLCertificate *cert;
00146         KSSLCertificateCache::KSSLCertificatePolicy policy;
00147         bool permanent;
00148         QDateTime expires;
00149         QStringList hosts;
00150         KSSLCNode() { cert = 0L;
00151                 policy = KSSLCertificateCache::Unknown; 
00152                 permanent = true;
00153             }
00154         ~KSSLCNode() { delete cert; }
00155 };
00156 
00157 
00158 
00159 void KSSLD::cacheSaveToDisk() {
00160 KSSLCNode *node;
00161 
00162     cfg->setGroup("General");
00163     cfg->writeEntry("policies version", 2);
00164 
00165     for (node = certList.first(); node; node = certList.next()) {
00166         if (node->permanent ||
00167             node->expires > QDateTime::currentDateTime()) {
00168             // First convert to a binary format and then write the
00169             // kconfig entry write the (CN, policy, cert) to
00170             // KSimpleConfig
00171             cfg->setGroup(node->cert->getMD5Digest());
00172             cfg->writeEntry("Certificate", node->cert->toString());
00173             cfg->writeEntry("Policy", node->policy);
00174             cfg->writeEntry("Expires", node->expires);
00175             cfg->writeEntry("Permanent", node->permanent);
00176             cfg->writeEntry("Hosts", node->hosts);
00177 
00178             // Also write the chain
00179             QStringList qsl;
00180             QPtrList<KSSLCertificate> cl =
00181                         node->cert->chain().getChain();
00182             for (KSSLCertificate *c = cl.first();
00183                             c != 0;
00184                             c = cl.next()) {
00185                 //kdDebug() << "Certificate in chain: "
00186                 //      <<  c->toString() << endl;
00187                 qsl << c->toString();
00188             }
00189 
00190             cl.setAutoDelete(true);
00191             cfg->writeEntry("Chain", qsl);
00192         }
00193     }  
00194 
00195     cfg->sync();
00196 
00197     // insure proper permissions -- contains sensitive data
00198     QString cfgName(KGlobal::dirs()->findResource("config", "ksslpolicies"));
00199 
00200     if (!cfgName.isEmpty()) {
00201 		::chmod(QFile::encodeName(cfgName), 0600);
00202     }
00203 }
00204 
00205 
00206 void KSSLD::cacheReload() {
00207     cacheClearList();
00208     delete cfg;
00209     cfg = new KSimpleConfig("ksslpolicies", false);
00210     cacheLoadDefaultPolicies();
00211 }
00212 
00213 
00214 void KSSLD::cacheClearList() {
00215 KSSLCNode *node;
00216 
00217     for (node = certList.first(); node; node = certList.next()) {
00218         certList.remove(node);
00219         delete node;
00220     }
00221 
00222     skEmail.clear();
00223     skMD5Digest.clear();
00224 }
00225 
00226 
00227 void KSSLD::cacheLoadDefaultPolicies() {
00228 QStringList groups = cfg->groupList();
00229 
00230     for (QStringList::Iterator i = groups.begin();
00231                 i != groups.end();
00232                 ++i) {
00233         if ((*i).isEmpty() || *i == "General") {
00234             continue;
00235         }
00236 
00237         cfg->setGroup(*i);
00238 
00239         // remove it if it has expired
00240         if (!cfg->readBoolEntry("Permanent") &&
00241             cfg->readDateTimeEntry("Expires") <
00242                 QDateTime::currentDateTime()) {
00243             cfg->deleteGroup(*i);
00244             continue;
00245         }
00246 
00247         QCString encodedCert;
00248         KSSLCertificate *newCert;
00249 
00250         encodedCert = cfg->readEntry("Certificate").local8Bit();
00251             newCert = KSSLCertificate::fromString(encodedCert);
00252 
00253         if (!newCert) {
00254                continue;
00255         }
00256 
00257         KSSLCNode *n = new KSSLCNode;
00258         n->cert = newCert;
00259         n->policy = (KSSLCertificateCache::KSSLCertificatePolicy) cfg->readNumEntry("Policy");
00260         n->permanent = cfg->readBoolEntry("Permanent");
00261         n->expires = cfg->readDateTimeEntry("Expires");
00262         n->hosts = cfg->readListEntry("Hosts");
00263         newCert->chain().setCertChain(cfg->readListEntry("Chain"));
00264         certList.append(n); 
00265         searchAddCert(newCert);
00266     }
00267 }
00268 
00269 
00270 void KSSLD::cacheAddCertificate(KSSLCertificate cert, 
00271             KSSLCertificateCache::KSSLCertificatePolicy policy,
00272             bool permanent) {
00273 KSSLCNode *node;
00274 
00275     for (node = certList.first(); node; node = certList.next()) {
00276         if (cert == *(node->cert)) {
00277             node->policy = policy;
00278             node->permanent = permanent;
00279 
00280             if (!permanent) {
00281                 node->expires = QDateTime::currentDateTime();
00282                 // FIXME: make this configurable
00283                 node->expires = node->expires.addSecs(3600);
00284             }
00285 
00286             cacheSaveToDisk();
00287             return;
00288         }
00289     }
00290 
00291     KSSLCNode *n = new KSSLCNode;
00292     n->cert = cert.replicate();
00293     n->policy = policy;
00294     n->permanent = permanent;
00295     // remove the old one
00296     cacheRemoveByCertificate(*(n->cert));
00297     certList.prepend(n); 
00298 
00299     if (!permanent) {
00300         n->expires = QDateTime::currentDateTime();
00301         n->expires = n->expires.addSecs(3600);
00302     }
00303 
00304     searchAddCert(n->cert);
00305     cacheSaveToDisk();
00306 }
00307 
00308 
00309 KSSLCertificateCache::KSSLCertificatePolicy KSSLD::cacheGetPolicyByCN(QString cn) {
00310 KSSLCNode *node;
00311 
00312     for (node = certList.first(); node; node = certList.next()) {
00313         if (KSSLX509Map(node->cert->getSubject()).getValue("CN") == cn) {
00314             if (!node->permanent &&
00315                 node->expires < QDateTime::currentDateTime()) {
00316                 certList.remove(node);
00317                 cfg->deleteGroup(node->cert->getMD5Digest());
00318                 delete node;
00319                 continue;
00320             }
00321 
00322             certList.remove(node);
00323             certList.prepend(node);
00324             cacheSaveToDisk();
00325             return node->policy;
00326         }
00327     }
00328 
00329     cacheSaveToDisk();
00330 
00331 return KSSLCertificateCache::Unknown;
00332 }
00333 
00334 
00335 KSSLCertificateCache::KSSLCertificatePolicy KSSLD::cacheGetPolicyByCertificate(KSSLCertificate cert) {
00336 KSSLCNode *node;
00337 
00338     for (node = certList.first(); node; node = certList.next()) {
00339         if (cert == *(node->cert)) {  
00340             if (!node->permanent &&
00341                 node->expires < QDateTime::currentDateTime()) {
00342                 certList.remove(node);
00343                 cfg->deleteGroup(node->cert->getMD5Digest());
00344                 delete node;
00345                 cacheSaveToDisk();
00346                 return KSSLCertificateCache::Unknown;
00347             }
00348 
00349             certList.remove(node);
00350             certList.prepend(node);
00351             return node->policy;
00352         }
00353     }
00354 
00355 return KSSLCertificateCache::Unknown;
00356 }
00357 
00358 
00359 bool KSSLD::cacheSeenCN(QString cn) {
00360 KSSLCNode *node;
00361 
00362     for (node = certList.first(); node; node = certList.next()) {
00363         if (KSSLX509Map(node->cert->getSubject()).getValue("CN") == cn) {
00364             if (!node->permanent &&
00365                 node->expires < QDateTime::currentDateTime()) {
00366                 certList.remove(node);
00367                 cfg->deleteGroup(node->cert->getMD5Digest());
00368                 delete node;
00369                 cacheSaveToDisk();
00370                 continue;
00371             }
00372 
00373             certList.remove(node);
00374             certList.prepend(node);
00375             return true;
00376         }
00377     }
00378 
00379 return false;
00380 }
00381 
00382 
00383 bool KSSLD::cacheSeenCertificate(KSSLCertificate cert) {
00384 KSSLCNode *node;
00385 
00386     for (node = certList.first(); node; node = certList.next()) {
00387         if (cert == *(node->cert)) {
00388             if (!node->permanent &&
00389                 node->expires < QDateTime::currentDateTime()) {
00390                 certList.remove(node);
00391                 cfg->deleteGroup(node->cert->getMD5Digest());
00392                 delete node;
00393                 cacheSaveToDisk();
00394                 return false;
00395             }
00396 
00397             certList.remove(node);
00398             certList.prepend(node);
00399             return true;
00400         }
00401     }
00402 
00403 return false;
00404 }
00405 
00406 
00407 bool KSSLD::cacheIsPermanent(KSSLCertificate cert) {
00408 KSSLCNode *node;
00409 
00410     for (node = certList.first(); node; node = certList.next()) {
00411         if (cert == *(node->cert)) {
00412             if (!node->permanent && node->expires <
00413                     QDateTime::currentDateTime()) {
00414                 certList.remove(node);
00415                 cfg->deleteGroup(node->cert->getMD5Digest());
00416                 delete node;
00417                 cacheSaveToDisk();
00418                 return false;
00419             }
00420 
00421             certList.remove(node);
00422             certList.prepend(node);
00423             return node->permanent;
00424         }
00425     }
00426 
00427 return false;
00428 }
00429 
00430 
00431 bool KSSLD::cacheRemoveBySubject(QString subject) {
00432 KSSLCNode *node;
00433 bool gotOne = false;
00434 
00435     for (node = certList.first(); node; node = certList.next()) {
00436         if (node->cert->getSubject() == subject) {
00437             certList.remove(node);
00438             cfg->deleteGroup(node->cert->getMD5Digest());
00439             searchRemoveCert(node->cert);
00440             delete node;
00441             gotOne = true;
00442         }
00443     }
00444 
00445     cacheSaveToDisk();
00446 
00447 return gotOne;
00448 }
00449 
00450 
00451 bool KSSLD::cacheRemoveByCN(QString cn) {
00452 KSSLCNode *node;
00453 bool gotOne = false;
00454 
00455     for (node = certList.first(); node; node = certList.next()) {
00456         if (KSSLX509Map(node->cert->getSubject()).getValue("CN") == cn) {
00457             certList.remove(node);
00458             cfg->deleteGroup(node->cert->getMD5Digest());
00459             searchRemoveCert(node->cert);
00460             delete node;
00461             gotOne = true;
00462         }
00463     }
00464 
00465     cacheSaveToDisk();
00466 
00467 return gotOne;
00468 }
00469 
00470 
00471 bool KSSLD::cacheRemoveByCertificate(KSSLCertificate cert) {
00472 KSSLCNode *node;
00473 
00474     for (node = certList.first(); node; node = certList.next()) {
00475         if (cert == *(node->cert)) {
00476             certList.remove(node);
00477             cfg->deleteGroup(node->cert->getMD5Digest());
00478             searchRemoveCert(node->cert);
00479             delete node;
00480             cacheSaveToDisk();
00481             return true;
00482         }
00483     }
00484 
00485 return false;
00486 }
00487 
00488 
00489 bool KSSLD::cacheModifyByCN(QString cn,
00490                             KSSLCertificateCache::KSSLCertificatePolicy policy,                             bool permanent,
00491                             QDateTime expires) {
00492 KSSLCNode *node;
00493 
00494     for (node = certList.first(); node; node = certList.next()) {
00495         if (KSSLX509Map(node->cert->getSubject()).getValue("CN") == cn) {
00496             node->permanent = permanent;
00497             node->expires = expires;
00498             node->policy = policy;
00499             certList.remove(node);
00500             certList.prepend(node);
00501             cacheSaveToDisk();
00502             return true;
00503         }
00504     }
00505 
00506 return false;
00507 }
00508 
00509 
00510 bool KSSLD::cacheModifyByCertificate(KSSLCertificate cert,
00511                              KSSLCertificateCache::KSSLCertificatePolicy policy,
00512                  bool permanent,
00513                  QDateTime expires) {
00514 KSSLCNode *node;
00515 
00516     for (node = certList.first(); node; node = certList.next()) {
00517         if (cert == *(node->cert)) {
00518             node->permanent = permanent;
00519             node->expires = expires;
00520             node->policy = policy;
00521             certList.remove(node);
00522             certList.prepend(node);
00523             cacheSaveToDisk();
00524             return true;
00525         }
00526     }
00527 
00528 return false;
00529 }
00530 
00531 
00532 QStringList KSSLD::cacheGetHostList(KSSLCertificate cert) {
00533 KSSLCNode *node;
00534 
00535     for (node = certList.first(); node; node = certList.next()) {
00536         if (cert == *(node->cert)) {
00537             if (!node->permanent && node->expires <
00538                        QDateTime::currentDateTime()) {
00539                 certList.remove(node);
00540                 cfg->deleteGroup(node->cert->getMD5Digest());
00541                 searchRemoveCert(node->cert);
00542                 delete node;
00543                 cacheSaveToDisk();
00544                 return QStringList();
00545             }
00546 
00547             certList.remove(node);
00548             certList.prepend(node);
00549             return node->hosts;
00550         }
00551     }
00552 
00553 return QStringList();
00554 }
00555 
00556 
00557 bool KSSLD::cacheAddHost(KSSLCertificate cert, QString host) {
00558 KSSLCNode *node;
00559 
00560     if (host.isEmpty())
00561         return true;
00562 
00563     for (node = certList.first(); node; node = certList.next()) {
00564         if (cert == *(node->cert)) {
00565             if (!node->permanent && node->expires <
00566                         QDateTime::currentDateTime()) {
00567                 certList.remove(node);
00568                 cfg->deleteGroup(node->cert->getMD5Digest());
00569                 searchRemoveCert(node->cert);
00570                 delete node;
00571                 cacheSaveToDisk();
00572                 return false;
00573             }
00574 
00575             if (!node->hosts.contains(host)) {
00576                 node->hosts << host;
00577             }
00578 
00579             certList.remove(node);
00580             certList.prepend(node);
00581             cacheSaveToDisk();
00582             return true;
00583         }
00584     }
00585 
00586 return false;
00587 }
00588 
00589 
00590 bool KSSLD::cacheRemoveHost(KSSLCertificate cert, QString host) {
00591 KSSLCNode *node;
00592 
00593     for (node = certList.first(); node; node = certList.next()) {
00594         if (cert == *(node->cert)) {
00595             if (!node->permanent && node->expires <
00596                         QDateTime::currentDateTime()) {
00597                 certList.remove(node);
00598                 cfg->deleteGroup(node->cert->getMD5Digest());
00599                 searchRemoveCert(node->cert);
00600                 delete node;
00601                 cacheSaveToDisk();
00602                 return false;
00603             }
00604             node->hosts.remove(host);
00605             certList.remove(node);
00606             certList.prepend(node);
00607             cacheSaveToDisk();
00608             return true;
00609         }
00610     }
00611 
00612 return false;
00613 }
00614 
00615 
00616 
00617 
00619 
00620 void KSSLD::caVerifyUpdate() {
00621     QString path = KGlobal::dirs()->saveLocation("kssl") + "/ca-bundle.crt";
00622     if (!QFile::exists(path))
00623         return;
00624     
00625     cfg->setGroup(QString::null);
00626     Q_UINT32 newStamp = KGlobal::dirs()->calcResourceHash("config", "ksslcalist", true);
00627     Q_UINT32 oldStamp = cfg->readUnsignedNumEntry("ksslcalistStamp");
00628     if (oldStamp != newStamp)
00629     {
00630         caRegenerate();
00631         cfg->writeEntry("ksslcalistStamp", newStamp);
00632         cfg->sync();
00633     }
00634 }
00635 
00636 bool KSSLD::caRegenerate() {
00637 QString path = KGlobal::dirs()->saveLocation("kssl") + "/ca-bundle.crt";
00638 
00639 QFile out(path);
00640 
00641     if (!out.open(IO_WriteOnly))
00642         return false;
00643 
00644 KConfig cfg("ksslcalist", true, false);
00645 
00646 QStringList x = cfg.groupList();
00647 
00648     for (QStringList::Iterator i = x.begin();
00649                    i != x.end();
00650                    ++i) {
00651         if ((*i).isEmpty() || *i == "<default>") continue;
00652 
00653         cfg.setGroup(*i);
00654 
00655         if (!cfg.readBoolEntry("site", false)) continue;
00656 
00657         QString cert = cfg.readEntry("x509", "");
00658         if (cert.length() <= 0) continue;
00659 
00660         unsigned int xx = cert.length() - 1;
00661         for (unsigned int j = 0; j < xx/64; j++) {
00662             cert.insert(64*(j+1)+j, '\n');
00663         }
00664         out.writeBlock("-----BEGIN CERTIFICATE-----\n", 28);
00665         out.writeBlock(cert.latin1(), cert.length());
00666         out.writeBlock("\n-----END CERTIFICATE-----\n\n", 28);
00667         out.flush();
00668     }
00669 
00670 return true;
00671 }
00672 
00673 
00674 
00675 bool KSSLD::caAdd(QString certificate, bool ssl, bool email, bool code) {
00676 KSSLCertificate *x = KSSLCertificate::fromString(certificate.local8Bit());
00677 
00678     if (!x) return false;
00679 
00680 KConfig cfg("ksslcalist", false, false);
00681 
00682     cfg.setGroup(x->getSubject());
00683     cfg.writeEntry("x509", certificate);
00684     cfg.writeEntry("site", ssl);
00685     cfg.writeEntry("email", email);
00686     cfg.writeEntry("code", code);
00687 
00688     cfg.sync();
00689     delete x;
00690 
00691 return true;
00692 }
00693 
00694 
00699 static QStringList caReadCerticatesFromFile(QString filename) {
00700 
00701     QStringList certificates;
00702     QString certificate, temp;
00703     QFile file(filename);
00704 
00705     if (!file.open(IO_ReadOnly))
00706         return certificates;
00707 
00708     while (!file.atEnd()) {
00709         file.readLine(temp, 999);
00710         if (temp.startsWith("-----BEGIN CERTIFICATE-----")) {
00711             certificate = QString::null;
00712             continue;
00713         }
00714 
00715         if (temp.startsWith("-----END CERTIFICATE-----")) {
00716             certificates.append(certificate);
00717             certificate = QString::null;
00718             continue;
00719         }
00720 
00721         certificate += temp.stripWhiteSpace();
00722     }
00723 
00724     file.close();
00725 
00726     return certificates;
00727 }
00728 
00729 bool KSSLD::caAddFromFile(QString filename, bool ssl, bool email, bool code) {
00730 
00731     QStringList certificates;
00732     certificates = caReadCerticatesFromFile(filename);
00733     if (certificates.isEmpty())
00734         return false;
00735 
00736     bool ok = true;
00737 
00738     for (QStringList::Iterator it = certificates.begin();
00739                     it != certificates.end(); ++it ) {
00740         ok &= caAdd(*it, ssl, email, code);
00741     }
00742 
00743     return ok;
00744 }
00745 
00746 bool KSSLD::caRemoveFromFile(QString filename) {
00747 
00748     QStringList certificates;
00749     certificates = caReadCerticatesFromFile(filename);
00750     if (certificates.isEmpty())
00751         return false;
00752 
00753     bool ok = true;
00754 
00755     for (QStringList::Iterator it = certificates.begin();
00756                     it != certificates.end(); ++it ) {
00757         QString certificate = *it;
00758         KSSLCertificate *x = KSSLCertificate::fromString(certificate.local8Bit());
00759         ok &= x && caRemove(x->getSubject());
00760         delete x;
00761     }
00762 
00763     return ok;
00764 }
00765 
00766 
00767 QStringList KSSLD::caList() {
00768 QStringList x;
00769 KConfig cfg("ksslcalist", true, false);
00770 
00771     x = cfg.groupList();
00772     x.remove("<default>");
00773 
00774 return x;
00775 }
00776 
00777 
00778 bool KSSLD::caUseForSSL(QString subject) {
00779 KConfig cfg("ksslcalist", true, false);
00780 
00781     if (!cfg.hasGroup(subject))
00782         return false;
00783 
00784     cfg.setGroup(subject);
00785 return cfg.readBoolEntry("site", false);
00786 }
00787 
00788 
00789 
00790 bool KSSLD::caUseForEmail(QString subject) {
00791 KConfig cfg("ksslcalist", true, false);
00792 
00793     if (!cfg.hasGroup(subject))
00794         return false;
00795 
00796     cfg.setGroup(subject);
00797 return cfg.readBoolEntry("email", false);
00798 }
00799 
00800 
00801 
00802 bool KSSLD::caUseForCode(QString subject) {
00803 KConfig cfg("ksslcalist", true, false);
00804 
00805     if (!cfg.hasGroup(subject))
00806         return false;
00807 
00808     cfg.setGroup(subject);
00809 return cfg.readBoolEntry("code", false);
00810 }
00811 
00812 
00813 bool KSSLD::caRemove(QString subject) {
00814 KConfig cfg("ksslcalist", false, false);
00815     if (!cfg.hasGroup(subject))
00816         return false;
00817 
00818     cfg.deleteGroup(subject);
00819     cfg.sync();
00820 
00821 return true;
00822 }
00823 
00824 
00825 QString KSSLD::caGetCert(QString subject) {
00826 KConfig cfg("ksslcalist", true, false);
00827     if (!cfg.hasGroup(subject))
00828         return QString::null;
00829 
00830     cfg.setGroup(subject);
00831 
00832 return cfg.readEntry("x509", QString::null);
00833 }
00834 
00835 
00836 bool KSSLD::caSetUse(QString subject, bool ssl, bool email, bool code) {
00837 KConfig cfg("ksslcalist", false, false);
00838     if (!cfg.hasGroup(subject))
00839         return false;
00840 
00841     cfg.setGroup(subject);
00842 
00843     cfg.writeEntry("site", ssl);
00844     cfg.writeEntry("email", email);
00845     cfg.writeEntry("code", code);
00846     cfg.sync();
00847 
00848 return true;
00849 }
00850 
00852 
00853 void KSSLD::searchAddCert(KSSLCertificate *cert) {
00854     skMD5Digest.insert(cert->getMD5Digest(), cert, true);
00855 
00856     QStringList mails;
00857     cert->getEmails(mails);
00858     for(QStringList::const_iterator iter = mails.begin(); iter != mails.end(); ++iter) {
00859         QString email = static_cast<const QString &>(*iter).lower();
00860         QMap<QString, QPtrVector<KSSLCertificate> >::iterator it = skEmail.find(email);
00861 
00862         if (it == skEmail.end())
00863             it = skEmail.insert(email, QPtrVector<KSSLCertificate>());
00864 
00865         QPtrVector<KSSLCertificate> &elem = *it;
00866         
00867         if (elem.findRef(cert) == -1) {
00868             unsigned int n = 0;
00869             for(; n < elem.size(); n++) {
00870                 if (!elem.at(n)) {
00871                     elem.insert(n, cert);
00872                     break;
00873                 }
00874             }
00875             if (n == elem.size()) {
00876                 elem.resize(n+1);
00877                 elem.insert(n, cert);
00878             }
00879         }
00880     }   
00881 }
00882 
00883 
00884 void KSSLD::searchRemoveCert(KSSLCertificate *cert) {
00885     skMD5Digest.remove(cert->getMD5Digest());
00886 
00887     QStringList mails;
00888     cert->getEmails(mails);
00889     for(QStringList::const_iterator iter = mails.begin(); iter != mails.end(); ++iter) {
00890         QMap<QString, QPtrVector<KSSLCertificate> >::iterator it = skEmail.find(static_cast<const QString &>(*iter).lower());
00891 
00892         if (it == skEmail.end())
00893                break;
00894 
00895         QPtrVector<KSSLCertificate> &elem = *it;
00896 
00897         int n = elem.findRef(cert);
00898         if (n != -1)
00899             elem.remove(n);
00900     }
00901 }   
00902 
00903 
00904 QStringList KSSLD::getKDEKeyByEmail(const QString &email) {
00905     QStringList rc;
00906     QMap<QString, QPtrVector<KSSLCertificate> >::iterator it = skEmail.find(email.lower());
00907 
00908     kdDebug() << "GETKDEKey " << email.latin1() << endl;
00909 
00910     if (it == skEmail.end())
00911         return rc;
00912 
00913     QPtrVector<KSSLCertificate> &elem = *it;
00914     for (unsigned int n = 0; n < elem.size(); n++) {
00915         KSSLCertificate *cert = elem.at(n);
00916         if (cert) {
00917             rc.append(cert->getKDEKey());
00918         }
00919     }
00920 
00921     kdDebug() << "ergebnisse: " << rc.size() << " " << elem.size() << endl;
00922     return rc;
00923 }
00924 
00925 
00926 KSSLCertificate KSSLD::getCertByMD5Digest(const QString &key) {
00927     QMap<QString, KSSLCertificate *>::iterator iter = skMD5Digest.find(key);
00928     
00929     kdDebug() << "Searching cert for " << key.latin1() << endl;
00930 
00931     if (iter != skMD5Digest.end())
00932         return **iter;
00933     
00934     KSSLCertificate rc; // FIXME: Better way to return a not found condition?
00935     kdDebug() << "Not found: " << rc.toString().latin1() << endl;
00936     return rc;
00937 }   
00938 
00939 
00941 
00942 //
00943 //  Certificate Home methods
00944 //
00945 
00946 QStringList KSSLD::getHomeCertificateList() {
00947     return KSSLCertificateHome::getCertificateList();
00948 }
00949 
00950 bool KSSLD::addHomeCertificateFile(QString filename, QString password, bool storePass) {
00951     return KSSLCertificateHome::addCertificate(filename, password, storePass);
00952 }
00953 
00954 bool KSSLD::addHomeCertificatePKCS12(QString base64cert, QString passToStore) {
00955     bool ok;
00956     KSSLPKCS12 *pkcs12 = KSSLPKCS12::fromString(base64cert, passToStore);
00957     ok = KSSLCertificateHome::addCertificate(pkcs12, passToStore);
00958     delete pkcs12;
00959     return ok;
00960 }
00961 
00962 bool KSSLD::deleteHomeCertificateByFile(QString filename, QString password) {
00963     return KSSLCertificateHome::deleteCertificate(filename, password);
00964 }
00965 
00966 bool KSSLD::deleteHomeCertificateByPKCS12(QString base64cert, QString password) {
00967     bool ok;
00968     KSSLPKCS12 *pkcs12 = KSSLPKCS12::fromString(base64cert, password);
00969     ok = KSSLCertificateHome::deleteCertificate(pkcs12);
00970     delete pkcs12;
00971     return ok;
00972 }
00973 
00974 bool KSSLD::deleteHomeCertificateByName(QString name) {
00975     return KSSLCertificateHome::deleteCertificateByName(name);
00976 }
00977 
00978 
00979 
00981 
00982 #include "kssld.moc"
00983 
00984 
00985 /*
00986 
00987   DESIGN     - KSSLCertificateCache
00988   ------
00989 
00990   This is the first implementation and I think this cache actually needs
00991   experimentation to determine which implementation works best.  My current
00992   options are:
00993 
00994    (1) Store copies of the X509 certificates in a QPtrList using a self
00995        organizing heuristic as described by Munro and Suwanda.
00996    (2) Store copies of the X509 certificates in a tree structure, perhaps
00997        a redblack tree, avl tree, or even just a simple binary tree.
00998    (3) Store the CN's in a tree or list and use them as a hash to retrieve
00999        the X509 certificates.
01000    (4) Create "nodes" containing the X509 certificate and place them in
01001        two structures concurrently, one organized by CN, the other by
01002        X509 serial number.
01003 
01004   This implementation uses (1).  (4) is definitely attractive, but I don't
01005   think it will be necessary to go so crazy with performance, and perhaps
01006   end up performing poorly in situations where there are very few entries in
01007   the cache (which is most likely the case most of the time).  The style of
01008   heuristic is move-to-front, not swap-forward.  This seems to make more
01009   sense because the typical user will hit a site at least a few times in a
01010   row before moving to a new one.
01011 
01012   What I worry about most with respect to performance is that cryptographic
01013   routines are expensive and if we have to perform them on each X509
01014   certificate until the right one is found, we will perform poorly.
01015 
01016   All in all, this code is actually quite crucial for performance on SSL
01017   website, especially those with many image files loaded via SSL.  If a
01018   site loads 15 images, we will have to run through this code 15 times.
01019   A heuristic for self organization will make each successive lookup faster.
01020   Sounds good, doesn't it?
01021 
01022   DO NOT ATTEMPT TO GUESS WHICH CERTIFICATES ARE ACCEPTIBLE IN YOUR CODE!!
01023   ALWAYS USE THE CACHE.  IT MAY CHECK THINGS THAT YOU DON'T THINK OF, AND
01024   ALSO IF THERE IS A BUG IN THE CHECKING CODE, IF IT IS ALL CONTAINED IN
01025   THIS LIBRARY, A MINOR FIX WILL FIX ALL APPLICATIONS.
01026  */
01027 

kio

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

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
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