kio Library API Documentation

kssld.cpp

00001 /*
00002    This file is part of the KDE libraries
00003 
00004    Copyright (c) 2001-2003 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., 59 Temple Place - Suite 330,
00019    Boston, MA 02111-1307, 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 <ksslx509map.h>
00035 #include <qptrlist.h>
00036 #include <sys/types.h>
00037 #include <sys/stat.h>
00038 #include <stdlib.h>
00039 #include <pwd.h>
00040 #include <unistd.h>
00041 #include <qfile.h>
00042 #include <qsortedlist.h>
00043 #include <kglobal.h>
00044 #include <kstandarddirs.h>
00045 #include <kdebug.h>
00046 #include <qdatetime.h>
00047 
00048 #include <kmdcodec.h>
00049 #include <kopenssl.h>
00050 
00051 // See design notes at end
00052 
00053 extern "C" {
00054     KDEDModule *create_kssld(const QCString &name) {
00055         return new KSSLD(name);
00056     }
00057 
00058     void *__kde_do_unload;
00059 }
00060 
00061 
00062 KSSLD::KSSLD(const QCString &name) : KDEDModule(name)
00063 {
00064 // ----------------------- FOR THE CACHE ------------------------------------   
00065     cfg = new KSimpleConfig("ksslpolicies", false);
00066     KGlobal::dirs()->addResourceType("kssl", KStandardDirs::kde_default("data") + "kssl");
00067     caVerifyUpdate();
00068     cacheLoadDefaultPolicies();
00069     certList.setAutoDelete(false);
00070     kossl = KOSSL::self();
00071 
00072 // ----------------------- FOR THE HOME -------------------------------------
00073 }
00074   
00075 
00076 KSSLD::~KSSLD()
00077 {
00078 // ----------------------- FOR THE CACHE ------------------------------------   
00079     cacheClearList();
00080     delete cfg;
00081 
00082 // ----------------------- FOR THE HOME -------------------------------------
00083 }
00084 
00085   
00086 
00087 
00088 // A node in the cache
00089 class KSSLCNode {
00090     public:
00091         KSSLCertificate *cert;
00092         KSSLCertificateCache::KSSLCertificatePolicy policy;
00093         bool permanent;
00094         QDateTime expires;
00095         QStringList hosts;
00096         KSSLCNode() { cert = 0L;
00097                 policy = KSSLCertificateCache::Unknown; 
00098                 permanent = true;
00099             }
00100         ~KSSLCNode() { if (cert) delete cert; }
00101 };
00102 
00103 
00104 
00105 void KSSLD::cacheSaveToDisk() {
00106 KSSLCNode *node;
00107 
00108     for (node = certList.first(); node; node = certList.next()) {
00109         if (node->permanent ||
00110             node->expires > QDateTime::currentDateTime()) {
00111             // First convert to a binary format and then write the
00112             // kconfig entry write the (CN, policy, cert) to
00113             // KSimpleConfig
00114             cfg->setGroup(node->cert->getSubject());
00115             cfg->writeEntry("Certificate", node->cert->toString());
00116             cfg->writeEntry("Policy", node->policy);
00117             cfg->writeEntry("Expires", node->expires);
00118             cfg->writeEntry("Permanent", node->permanent);
00119             cfg->writeEntry("Hosts", node->hosts);
00120 
00121             // Also write the chain
00122             QStringList qsl;
00123             QPtrList<KSSLCertificate> cl =
00124                         node->cert->chain().getChain();
00125             for (KSSLCertificate *c = cl.first();
00126                             c != 0;
00127                             c = cl.next()) {
00128                 //kdDebug() << "Certificate in chain: "
00129                 //      <<  c->toString() << endl;
00130                 qsl << c->toString();
00131             }
00132 
00133             cl.setAutoDelete(true);
00134             cfg->writeEntry("Chain", qsl);
00135         }
00136     }  
00137 
00138     cfg->sync();
00139 
00140     // insure proper permissions -- contains sensitive data
00141     QString cfgName(KGlobal::dirs()->findResource("config", "ksslpolicies"));
00142 
00143     if (!cfgName.isEmpty()) {
00144         ::chmod(QFile::encodeName(cfgName), 0600);
00145     }
00146 }
00147 
00148 
00149 void KSSLD::cacheReload() {
00150     cacheClearList();
00151     delete cfg;
00152     cfg = new KSimpleConfig("ksslpolicies", false);
00153     cacheLoadDefaultPolicies();
00154 }
00155 
00156 
00157 void KSSLD::cacheClearList() {
00158 KSSLCNode *node;
00159 
00160     for (node = certList.first(); node; node = certList.next()) {
00161         certList.remove(node);
00162         delete node;
00163     }
00164 
00165     skEmail.clear();
00166     skMD5Digest.clear();
00167 }
00168 
00169 
00170 void KSSLD::cacheLoadDefaultPolicies() {
00171 QStringList groups = cfg->groupList();
00172 
00173     for (QStringList::Iterator i = groups.begin();
00174                 i != groups.end();
00175                 ++i) {
00176         if ((*i).length() == 0) {
00177             continue;
00178         }
00179 
00180         cfg->setGroup(*i);
00181 
00182         // remove it if it has expired
00183         if (!cfg->readBoolEntry("Permanent") &&
00184             cfg->readDateTimeEntry("Expires") <
00185                 QDateTime::currentDateTime()) {
00186             cfg->deleteGroup(*i);
00187             continue;
00188         }
00189 
00190         QCString encodedCert;
00191         KSSLCertificate *newCert;
00192 
00193         encodedCert = cfg->readEntry("Certificate").local8Bit();
00194             newCert = KSSLCertificate::fromString(encodedCert);
00195 
00196         if (!newCert) {
00197                continue;
00198         }
00199 
00200         KSSLCNode *n = new KSSLCNode;
00201         n->cert = newCert;
00202         n->policy = (KSSLCertificateCache::KSSLCertificatePolicy) cfg->readNumEntry("Policy");
00203         n->permanent = cfg->readBoolEntry("Permanent");
00204         n->expires = cfg->readDateTimeEntry("Expires");
00205         n->hosts = cfg->readListEntry("Hosts");
00206         newCert->chain().setChain(cfg->readListEntry("Chain"));
00207         certList.append(n); 
00208         searchAddCert(newCert);
00209     }
00210 }
00211 
00212 
00213 void KSSLD::cacheAddCertificate(KSSLCertificate cert, 
00214             KSSLCertificateCache::KSSLCertificatePolicy policy,
00215             bool permanent) {
00216 KSSLCNode *node;
00217 
00218     for (node = certList.first(); node; node = certList.next()) {
00219         if (cert == *(node->cert)) {
00220             node->policy = policy;
00221             node->permanent = permanent;
00222 
00223             if (!permanent) {
00224                 node->expires = QDateTime::currentDateTime();
00225                 // FIXME: make this configurable
00226                 node->expires = node->expires.addSecs(3600);
00227             }
00228 
00229             cacheSaveToDisk();
00230             return;
00231         }
00232     }
00233 
00234     KSSLCNode *n = new KSSLCNode;
00235     n->cert = cert.replicate();
00236     n->policy = policy;
00237     n->permanent = permanent;
00238     // remove the old one
00239     cacheRemoveBySubject(n->cert->getSubject());
00240     certList.prepend(n); 
00241 
00242     if (!permanent) {
00243         n->expires = QDateTime::currentDateTime();
00244         n->expires = n->expires.addSecs(3600);
00245     }
00246 
00247     searchAddCert(n->cert);
00248     cacheSaveToDisk();
00249 }
00250 
00251 
00252 KSSLCertificateCache::KSSLCertificatePolicy KSSLD::cacheGetPolicyByCN(QString cn) {
00253 KSSLCNode *node;
00254 
00255     for (node = certList.first(); node; node = certList.next()) {
00256         if (KSSLX509Map(node->cert->getSubject()).getValue("CN") == cn) {
00257             if (!node->permanent &&
00258                 node->expires < QDateTime::currentDateTime()) {
00259                 certList.remove(node);
00260                 cfg->deleteGroup(node->cert->getSubject());
00261                 delete node;
00262                 continue;
00263             }
00264 
00265             certList.remove(node);
00266             certList.prepend(node);
00267             cacheSaveToDisk();
00268             return node->policy;
00269         }
00270     }
00271 
00272     cacheSaveToDisk();
00273 
00274 return KSSLCertificateCache::Unknown;
00275 }
00276 
00277 
00278 KSSLCertificateCache::KSSLCertificatePolicy KSSLD::cacheGetPolicyByCertificate(KSSLCertificate cert) {
00279 KSSLCNode *node;
00280 
00281     for (node = certList.first(); node; node = certList.next()) {
00282         if (cert == *(node->cert)) {  
00283             if (!node->permanent &&
00284                 node->expires < QDateTime::currentDateTime()) {
00285                 certList.remove(node);
00286                 cfg->deleteGroup(node->cert->getSubject());
00287                 delete node;
00288                 cacheSaveToDisk();
00289                 return KSSLCertificateCache::Unknown;
00290             }
00291 
00292             certList.remove(node);
00293             certList.prepend(node);
00294             return node->policy;
00295         }
00296     }
00297 
00298 return KSSLCertificateCache::Unknown;
00299 }
00300 
00301 
00302 bool KSSLD::cacheSeenCN(QString cn) {
00303 KSSLCNode *node;
00304 
00305     for (node = certList.first(); node; node = certList.next()) {
00306         if (KSSLX509Map(node->cert->getSubject()).getValue("CN") == cn) {
00307             if (!node->permanent &&
00308                 node->expires < QDateTime::currentDateTime()) {
00309                 certList.remove(node);
00310                 cfg->deleteGroup(node->cert->getSubject());
00311                 delete node;
00312                 cacheSaveToDisk();
00313                 continue;
00314             }
00315 
00316             certList.remove(node);
00317             certList.prepend(node);
00318             return true;
00319         }
00320     }
00321 
00322 return false;
00323 }
00324 
00325 
00326 bool KSSLD::cacheSeenCertificate(KSSLCertificate cert) {
00327 KSSLCNode *node;
00328 
00329     for (node = certList.first(); node; node = certList.next()) {
00330         if (cert == *(node->cert)) {
00331             if (!node->permanent &&
00332                 node->expires < QDateTime::currentDateTime()) {
00333                 certList.remove(node);
00334                 cfg->deleteGroup(node->cert->getSubject());
00335                 delete node;
00336                 cacheSaveToDisk();
00337                 return false;
00338             }
00339 
00340             certList.remove(node);
00341             certList.prepend(node);
00342             return true;
00343         }
00344     }
00345 
00346 return false;
00347 }
00348 
00349 
00350 bool KSSLD::cacheIsPermanent(KSSLCertificate cert) {
00351 KSSLCNode *node;
00352 
00353     for (node = certList.first(); node; node = certList.next()) {
00354         if (cert == *(node->cert)) {
00355             if (!node->permanent && node->expires <
00356                     QDateTime::currentDateTime()) {
00357                 certList.remove(node);
00358                 cfg->deleteGroup(node->cert->getSubject());
00359                 delete node;
00360                 cacheSaveToDisk();
00361                 return false;
00362             }
00363 
00364             certList.remove(node);
00365             certList.prepend(node);
00366             return node->permanent;
00367         }
00368     }
00369 
00370 return false;
00371 }
00372 
00373 
00374 bool KSSLD::cacheRemoveBySubject(QString subject) {
00375 KSSLCNode *node;
00376 bool gotOne = false;
00377 
00378     for (node = certList.first(); node; node = certList.next()) {
00379         if (node->cert->getSubject() == subject) {
00380             certList.remove(node);
00381             cfg->deleteGroup(node->cert->getSubject());
00382             searchRemoveCert(node->cert);
00383             delete node;
00384             gotOne = true;
00385         }
00386     }
00387 
00388     cacheSaveToDisk();
00389 
00390 return gotOne;
00391 }
00392 
00393 
00394 bool KSSLD::cacheRemoveByCN(QString cn) {
00395 KSSLCNode *node;
00396 bool gotOne = false;
00397 
00398     for (node = certList.first(); node; node = certList.next()) {
00399         if (KSSLX509Map(node->cert->getSubject()).getValue("CN") == cn) {
00400             certList.remove(node);
00401             cfg->deleteGroup(node->cert->getSubject());
00402             searchRemoveCert(node->cert);
00403             delete node;
00404             gotOne = true;
00405         }
00406     }
00407 
00408     cacheSaveToDisk();
00409 
00410 return gotOne;
00411 }
00412 
00413 
00414 bool KSSLD::cacheRemoveByCertificate(KSSLCertificate cert) {
00415 KSSLCNode *node;
00416 
00417     for (node = certList.first(); node; node = certList.next()) {
00418         if (cert == *(node->cert)) {
00419             certList.remove(node);
00420             cfg->deleteGroup(node->cert->getSubject());
00421             searchRemoveCert(node->cert);
00422             delete node;
00423             cacheSaveToDisk();
00424             return true;
00425         }
00426     }
00427 
00428 return false;
00429 }
00430 
00431 
00432 bool KSSLD::cacheModifyByCN(QString cn,
00433                             KSSLCertificateCache::KSSLCertificatePolicy policy,                             bool permanent,
00434                             QDateTime expires) {
00435 KSSLCNode *node;
00436 
00437     for (node = certList.first(); node; node = certList.next()) {
00438         if (KSSLX509Map(node->cert->getSubject()).getValue("CN") == cn) {
00439             node->permanent = permanent;
00440             node->expires = expires;
00441             node->policy = policy;
00442             certList.remove(node);
00443             certList.prepend(node);
00444             cacheSaveToDisk();
00445             return true;
00446         }
00447     }
00448 
00449 return false;
00450 }
00451 
00452 
00453 bool KSSLD::cacheModifyByCertificate(KSSLCertificate cert,
00454                              KSSLCertificateCache::KSSLCertificatePolicy policy,
00455                  bool permanent,
00456                  QDateTime expires) {
00457 KSSLCNode *node;
00458 
00459     for (node = certList.first(); node; node = certList.next()) {
00460         if (cert == *(node->cert)) {
00461             node->permanent = permanent;
00462             node->expires = expires;
00463             node->policy = policy;
00464             certList.remove(node);
00465             certList.prepend(node);
00466             cacheSaveToDisk();
00467             return true;
00468         }
00469     }
00470 
00471 return false;
00472 }
00473 
00474 
00475 QStringList KSSLD::cacheGetHostList(KSSLCertificate cert) {
00476 KSSLCNode *node;
00477 
00478     for (node = certList.first(); node; node = certList.next()) {
00479         if (cert == *(node->cert)) {
00480             if (!node->permanent && node->expires <
00481                        QDateTime::currentDateTime()) {
00482                 certList.remove(node);
00483                 cfg->deleteGroup(node->cert->getSubject());
00484                 searchRemoveCert(node->cert);
00485                 delete node;
00486                 cacheSaveToDisk();
00487                 return QStringList();
00488             }
00489 
00490             certList.remove(node);
00491             certList.prepend(node);
00492             return node->hosts;
00493         }
00494     }
00495 
00496 return QStringList();
00497 }
00498 
00499 
00500 bool KSSLD::cacheAddHost(KSSLCertificate cert, QString host) {
00501 KSSLCNode *node;
00502 
00503     if (host.isEmpty())
00504         return true;
00505 
00506     for (node = certList.first(); node; node = certList.next()) {
00507         if (cert == *(node->cert)) {
00508             if (!node->permanent && node->expires <
00509                         QDateTime::currentDateTime()) {
00510                 certList.remove(node);
00511                 cfg->deleteGroup(node->cert->getSubject());
00512                 searchRemoveCert(node->cert);
00513                 delete node;
00514                 cacheSaveToDisk();
00515                 return false;
00516             }
00517 
00518             if (!node->hosts.contains(host)) {
00519                 node->hosts << host;
00520             }
00521 
00522             certList.remove(node);
00523             certList.prepend(node);
00524             cacheSaveToDisk();
00525             return true;
00526         }
00527     }
00528 
00529 return false;
00530 }
00531 
00532 
00533 bool KSSLD::cacheRemoveHost(KSSLCertificate cert, QString host) {
00534 KSSLCNode *node;
00535 
00536     for (node = certList.first(); node; node = certList.next()) {
00537         if (cert == *(node->cert)) {
00538             if (!node->permanent && node->expires <
00539                         QDateTime::currentDateTime()) {
00540                 certList.remove(node);
00541                 cfg->deleteGroup(node->cert->getSubject());
00542                 searchRemoveCert(node->cert);
00543                 delete node;
00544                 cacheSaveToDisk();
00545                 return false;
00546             }
00547             node->hosts.remove(host);
00548             certList.remove(node);
00549             certList.prepend(node);
00550             cacheSaveToDisk();
00551             return true;
00552         }
00553     }
00554 
00555 return false;
00556 }
00557 
00558 
00559 
00560 
00562 
00563 void KSSLD::caVerifyUpdate() {
00564     QString path = KGlobal::dirs()->saveLocation("kssl") + "/ca-bundle.crt";
00565     if (!QFile::exists(path))
00566         return;
00567     
00568     cfg->setGroup(QString::null);
00569     Q_UINT32 newStamp = KGlobal::dirs()->calcResourceHash("config", "ksslcalist", true);
00570     Q_UINT32 oldStamp = cfg->readUnsignedNumEntry("ksslcalistStamp");
00571     if (oldStamp != newStamp)
00572     {
00573         caRegenerate();
00574         cfg->writeEntry("ksslcalistStamp", newStamp);
00575         cfg->sync();
00576     }
00577 }
00578 
00579 bool KSSLD::caRegenerate() {
00580 QString path = KGlobal::dirs()->saveLocation("kssl") + "/ca-bundle.crt";
00581 
00582 QFile out(path);
00583 
00584     if (!out.open(IO_WriteOnly))
00585         return false;
00586 
00587 KConfig cfg("ksslcalist", true, false);
00588 
00589 QStringList x = cfg.groupList();
00590 
00591     for (QStringList::Iterator i = x.begin();
00592                    i != x.end();
00593                    ++i) {
00594         if ((*i).isEmpty() || *i == "<default>") continue;
00595 
00596         cfg.setGroup(*i);
00597 
00598         if (!cfg.readBoolEntry("site", false)) continue;
00599 
00600         QString cert = cfg.readEntry("x509", "");
00601         if (cert.length() <= 0) continue;
00602 
00603         unsigned int xx = cert.length() - 1;
00604         for (unsigned int j = 0; j < xx/64; j++) {
00605             cert.insert(64*(j+1)+j, '\n');
00606         }
00607         out.writeBlock("-----BEGIN CERTIFICATE-----\n", 28);
00608         out.writeBlock(cert.latin1(), cert.length());
00609         out.writeBlock("\n-----END CERTIFICATE-----\n\n", 28);
00610         out.flush();
00611     }
00612 
00613 return true;
00614 }
00615 
00616 
00617 
00618 bool KSSLD::caAdd(QString certificate, bool ssl, bool email, bool code) {
00619 KSSLCertificate *x = KSSLCertificate::fromString(certificate.local8Bit());
00620 
00621     if (!x) return false;
00622 
00623 KConfig cfg("ksslcalist", false, false);
00624 
00625     cfg.setGroup(x->getSubject());
00626     cfg.writeEntry("x509", certificate);
00627     cfg.writeEntry("site", ssl);
00628     cfg.writeEntry("email", email);
00629     cfg.writeEntry("code", code);
00630 
00631     cfg.sync();
00632     delete x;
00633 
00634 return true;
00635 }
00636 
00637 
00638 QStringList KSSLD::caList() {
00639 QStringList x;
00640 KConfig cfg("ksslcalist", true, false);
00641 
00642     x = cfg.groupList();
00643     x.remove("<default>");
00644 
00645 return x;
00646 }
00647 
00648 
00649 bool KSSLD::caUseForSSL(QString subject) {
00650 KConfig cfg("ksslcalist", true, false);
00651 
00652     if (!cfg.hasGroup(subject))
00653         return false;
00654 
00655     cfg.setGroup(subject);
00656 return cfg.readBoolEntry("site", false);
00657 }
00658 
00659 
00660 
00661 bool KSSLD::caUseForEmail(QString subject) {
00662 KConfig cfg("ksslcalist", true, false);
00663 
00664     if (!cfg.hasGroup(subject))
00665         return false;
00666 
00667     cfg.setGroup(subject);
00668 return cfg.readBoolEntry("email", false);
00669 }
00670 
00671 
00672 
00673 bool KSSLD::caUseForCode(QString subject) {
00674 KConfig cfg("ksslcalist", true, false);
00675 
00676     if (!cfg.hasGroup(subject))
00677         return false;
00678 
00679     cfg.setGroup(subject);
00680 return cfg.readBoolEntry("code", false);
00681 }
00682 
00683 
00684 bool KSSLD::caRemove(QString subject) {
00685 KConfig cfg("ksslcalist", false, false);
00686     if (!cfg.hasGroup(subject))
00687         return false;
00688 
00689     cfg.deleteGroup(subject);
00690     cfg.sync();
00691 
00692 return true;
00693 }
00694 
00695 
00696 QString KSSLD::caGetCert(QString subject) {
00697 KConfig cfg("ksslcalist", true, false);
00698     if (!cfg.hasGroup(subject))
00699         return QString::null;
00700 
00701     cfg.setGroup(subject);
00702 
00703 return cfg.readEntry("x509", QString::null);
00704 }
00705 
00706 
00707 bool KSSLD::caSetUse(QString subject, bool ssl, bool email, bool code) {
00708 KConfig cfg("ksslcalist", false, false);
00709     if (!cfg.hasGroup(subject))
00710         return false;
00711 
00712     cfg.setGroup(subject);
00713 
00714     cfg.writeEntry("site", ssl);
00715     cfg.writeEntry("email", email);
00716     cfg.writeEntry("code", code);
00717     cfg.sync();
00718 
00719 return true;
00720 }
00721 
00723 
00724 void KSSLD::searchAddCert(KSSLCertificate *cert) {
00725     skMD5Digest.insert(cert->getMD5DigestText(), cert, true);
00726 
00727     QStringList mails;
00728     cert->getEmails(mails);
00729     for(QStringList::const_iterator iter = mails.begin(); iter != mails.end(); iter++) {
00730         QString email = static_cast<const QString &>(*iter).lower();
00731         QMap<QString, QPtrVector<KSSLCertificate> >::iterator it = skEmail.find(email);
00732 
00733         if (it == skEmail.end())
00734             it = skEmail.insert(email, QPtrVector<KSSLCertificate>());
00735 
00736         QPtrVector<KSSLCertificate> &elem = *it;
00737         
00738         if (elem.findRef(cert) == -1) {
00739             unsigned int n = 0;
00740             for(; n < elem.size(); n++) {
00741                 if (!elem.at(n)) {
00742                     elem.insert(n, cert);
00743                     break;
00744                 }
00745             }
00746             if (n == elem.size()) {
00747                 elem.resize(n+1);
00748                 elem.insert(n, cert);
00749             }
00750         }
00751     }   
00752 }
00753 
00754 
00755 void KSSLD::searchRemoveCert(KSSLCertificate *cert) {
00756     skMD5Digest.remove(cert->getMD5DigestText());
00757 
00758     QStringList mails;
00759     cert->getEmails(mails);
00760     for(QStringList::const_iterator iter = mails.begin(); iter != mails.end(); iter++) {
00761         QMap<QString, QPtrVector<KSSLCertificate> >::iterator it = skEmail.find(static_cast<const QString &>(*iter).lower());
00762 
00763         if (it == skEmail.end())
00764                break;
00765 
00766         QPtrVector<KSSLCertificate> &elem = *it;
00767 
00768         int n = elem.findRef(cert);
00769         if (n != -1)
00770             elem.remove(n);
00771     }
00772 }   
00773 
00774 
00775 QStringList KSSLD::getKDEKeyByEmail(const QString &email) {
00776     QStringList rc;
00777     QMap<QString, QPtrVector<KSSLCertificate> >::iterator it = skEmail.find(email.lower());
00778 
00779     kdDebug() << "GETKDEKey " << email.latin1() << endl;
00780 
00781     if (it == skEmail.end())
00782         return rc;
00783 
00784     QPtrVector<KSSLCertificate> &elem = *it;
00785     for (unsigned int n = 0; n < elem.size(); n++) {
00786         KSSLCertificate *cert = elem.at(n);
00787         if (cert) {
00788             rc.append(cert->getKDEKey());
00789         }
00790     }
00791 
00792     kdDebug() << "ergebnisse: " << rc.size() << " " << elem.size() << endl;
00793     return rc;
00794 }
00795 
00796 
00797 KSSLCertificate KSSLD::getCertByMD5Digest(const QString &key) {
00798     QMap<QString, KSSLCertificate *>::iterator iter = skMD5Digest.find(key);
00799     
00800     kdDebug() << "Searching cert for " << key.latin1() << endl;
00801 
00802     if (iter != skMD5Digest.end())
00803         return **iter;
00804     
00805     KSSLCertificate rc; // FIXME: Better way to return a not found condition?
00806     kdDebug() << "Not found: " << rc.toString().latin1() << endl;
00807     return rc;
00808 }   
00809 
00810 
00812 
00813 
00814 
00815 
00816 
00818 
00819 #include "kssld.moc"
00820 
00821 
00822 /*
00823 
00824   DESIGN     - KSSLCertificateCache
00825   ------
00826 
00827   This is the first implementation and I think this cache actually needs
00828   experimentation to determine which implementation works best.  My current
00829   options are:
00830 
00831    (1) Store copies of the X509 certificates in a QPtrList using a self
00832        organizing heuristic as described by Munro and Suwanda.
00833    (2) Store copies of the X509 certificates in a tree structure, perhaps
00834        a redblack tree, avl tree, or even just a simple binary tree.
00835    (3) Store the CN's in a tree or list and use them as a hash to retrieve
00836        the X509 certificates.
00837    (4) Create "nodes" containing the X509 certificate and place them in
00838        two structures concurrently, one organized by CN, the other by
00839        X509 serial number.
00840 
00841   This implementation uses (1).  (4) is definitely attractive, but I don't
00842   think it will be necessary to go so crazy with performance, and perhaps
00843   end up performing poorly in situations where there are very few entries in
00844   the cache (which is most likely the case most of the time).  The style of
00845   heuristic is move-to-front, not swap-forward.  This seems to make more
00846   sense because the typical user will hit a site at least a few times in a
00847   row before moving to a new one.
00848 
00849   What I worry about most with respect to performance is that cryptographic
00850   routines are expensive and if we have to perform them on each X509
00851   certificate until the right one is found, we will perform poorly.
00852 
00853   All in all, this code is actually quite crucial for performance on SSL
00854   website, especially those with many image files loaded via SSL.  If a
00855   site loads 15 images, we will have to run through this code 15 times.
00856   A heuristic for self organization will make each successive lookup faster.
00857   Sounds good, doesn't it?
00858 
00859   DO NOT ATTEMPT TO GUESS WHICH CERTIFICATES ARE ACCEPTIBLE IN YOUR CODE!!
00860   ALWAYS USE THE CACHE.  IT MAY CHECK THINGS THAT YOU DON'T THINK OF, AND
00861   ALSO IF THERE IS A BUG IN THE CHECKING CODE, IF IT IS ALL CONTAINED IN
00862   THIS LIBRARY, A MINOR FIX WILL FIX ALL APPLICATIONS.
00863  */
00864 
KDE Logo
This file is part of the documentation for kio Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Mar 3 19:23:43 2005 by doxygen 1.3.6 written by Dimitri van Heesch, © 1997-2003