# kio Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kssld.cpp

    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., 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 <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

This file is part of the documentation for kio Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:24:04 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003