00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #define SAVE_DELAY 3 // Save after 3 minutes
00029
00030 #include <unistd.h>
00031
00032 #include <qtimer.h>
00033 #include <qptrlist.h>
00034 #include <qfile.h>
00035
00036 #include <dcopclient.h>
00037
00038 #include <kconfig.h>
00039 #include <kdebug.h>
00040 #include <kapplication.h>
00041 #include <kcmdlineargs.h>
00042 #include <kstandarddirs.h>
00043
00044 #include "kcookiejar.h"
00045 #include "kcookiewin.h"
00046 #include "kcookieserver.h"
00047
00048 extern "C" {
00049 KDE_EXPORT KDEDModule *create_kcookiejar(const QCString &name)
00050 {
00051 return new KCookieServer(name);
00052 }
00053 }
00054
00055
00056
00057 enum CookieDetails { CF_DOMAIN=0, CF_PATH, CF_NAME, CF_HOST,
00058 CF_VALUE, CF_EXPIRE, CF_PROVER, CF_SECURE };
00059
00060
00061 class CookieRequest {
00062 public:
00063 DCOPClient *client;
00064 DCOPClientTransaction *transaction;
00065 QString url;
00066 bool DOM;
00067 long windowId;
00068 };
00069
00070 template class QPtrList<CookieRequest>;
00071
00072 class RequestList : public QPtrList<CookieRequest>
00073 {
00074 public:
00075 RequestList() : QPtrList<CookieRequest>() { }
00076 };
00077
00078 KCookieServer::KCookieServer(const QCString &name)
00079 :KDEDModule(name)
00080 {
00081 mOldCookieServer = new DCOPClient();
00082 mOldCookieServer->registerAs("kcookiejar", false);
00083 mOldCookieServer->setDaemonMode( true );
00084 mCookieJar = new KCookieJar;
00085 mPendingCookies = new KHttpCookieList;
00086 mPendingCookies->setAutoDelete(true);
00087 mRequestList = new RequestList;
00088 mAdvicePending = false;
00089 mTimer = 0;
00090 mConfig = new KConfig("kcookiejarrc");
00091 mCookieJar->loadConfig( mConfig );
00092
00093 QString filename = locateLocal("data", "kcookiejar/cookies");
00094
00095
00096 QString filenameOld = locate("data", "kfm/cookies");
00097 if (!filenameOld.isEmpty())
00098 {
00099 mCookieJar->loadCookies( filenameOld );
00100 if (mCookieJar->saveCookies( filename))
00101 {
00102 unlink(QFile::encodeName(filenameOld));
00103 }
00104 }
00105 else
00106 {
00107 mCookieJar->loadCookies( filename);
00108 }
00109 connect(this, SIGNAL(windowUnregistered(long)),
00110 this, SLOT(slotDeleteSessionCookies(long)));
00111 }
00112
00113 KCookieServer::~KCookieServer()
00114 {
00115 if (mCookieJar->changed())
00116 slotSave();
00117 delete mOldCookieServer;
00118 delete mCookieJar;
00119 delete mTimer;
00120 delete mPendingCookies;
00121 delete mConfig;
00122 }
00123
00124 bool KCookieServer::cookiesPending( const QString &url, KHttpCookieList *cookieList )
00125 {
00126 QString fqdn;
00127 QStringList domains;
00128 QString path;
00129
00130 if (mPendingCookies->isEmpty())
00131 return false;
00132 if (!KCookieJar::parseURL(url, fqdn, path))
00133 return false;
00134
00135 mCookieJar->extractDomains( fqdn, domains );
00136 for( KHttpCookie *cookie = mPendingCookies->first();
00137 cookie != 0L;
00138 cookie = mPendingCookies->next())
00139 {
00140 if (cookie->match( fqdn, domains, path))
00141 {
00142 if (!cookieList)
00143 return true;
00144 cookieList->append(cookie);
00145 }
00146 }
00147 if (!cookieList)
00148 return false;
00149 return cookieList->isEmpty();
00150 }
00151
00152 void KCookieServer::addCookies( const QString &url, const QCString &cookieHeader,
00153 long windowId, bool useDOMFormat )
00154 {
00155 KHttpCookieList cookieList;
00156 if (useDOMFormat)
00157 cookieList = mCookieJar->makeDOMCookies(url, cookieHeader, windowId);
00158 else
00159 cookieList = mCookieJar->makeCookies(url, cookieHeader, windowId);
00160
00161 checkCookies(&cookieList);
00162
00163 for(KHttpCookiePtr cookie = cookieList.first(); cookie; cookie = cookieList.first())
00164 mPendingCookies->append(cookieList.take());
00165
00166 if (!mAdvicePending)
00167 {
00168 mAdvicePending = true;
00169 while (!mPendingCookies->isEmpty())
00170 {
00171 checkCookies(0);
00172 }
00173 mAdvicePending = false;
00174 }
00175 }
00176
00177 void KCookieServer::checkCookies( KHttpCookieList *cookieList)
00178 {
00179 KHttpCookieList *list;
00180
00181 if (cookieList)
00182 list = cookieList;
00183 else
00184 list = mPendingCookies;
00185
00186 KHttpCookiePtr cookie = list->first();
00187 while (cookie)
00188 {
00189 KCookieAdvice advice = mCookieJar->cookieAdvice(cookie);
00190 switch(advice)
00191 {
00192 case KCookieAccept:
00193 list->take();
00194 mCookieJar->addCookie(cookie);
00195 cookie = list->current();
00196 break;
00197
00198 case KCookieReject:
00199 list->take();
00200 delete cookie;
00201 cookie = list->current();
00202 break;
00203
00204 default:
00205 cookie = list->next();
00206 break;
00207 }
00208 }
00209
00210 if (cookieList || list->isEmpty())
00211 return;
00212
00213 KHttpCookiePtr currentCookie = mPendingCookies->first();
00214
00215 KHttpCookieList currentList;
00216 currentList.append(currentCookie);
00217 QString currentHost = currentCookie->host();
00218
00219 cookie = mPendingCookies->next();
00220 while (cookie)
00221 {
00222 if (cookie->host() == currentHost)
00223 {
00224 currentList.append(cookie);
00225 }
00226 cookie = mPendingCookies->next();
00227 }
00228
00229 KCookieWin *kw = new KCookieWin( 0L, currentList,
00230 mCookieJar->preferredDefaultPolicy(),
00231 mCookieJar->showCookieDetails() );
00232 KCookieAdvice userAdvice = kw->advice(mCookieJar, currentCookie);
00233 delete kw;
00234
00235 mCookieJar->saveConfig( mConfig );
00236
00237
00238
00239 cookie = mPendingCookies->first();
00240 while (cookie)
00241 {
00242 if (cookie->host() == currentHost)
00243 {
00244 switch(userAdvice)
00245 {
00246 case KCookieAccept:
00247 mPendingCookies->take();
00248 mCookieJar->addCookie(cookie);
00249 cookie = mPendingCookies->current();
00250 break;
00251
00252 case KCookieReject:
00253 mPendingCookies->take();
00254 delete cookie;
00255 cookie = mPendingCookies->current();
00256 break;
00257
00258 default:
00259 qWarning(__FILE__":%d Problen!", __LINE__);
00260 cookie = mPendingCookies->next();
00261 break;
00262 }
00263 }
00264 else
00265 {
00266 cookie = mPendingCookies->next();
00267 }
00268 }
00269
00270
00271
00272 for ( CookieRequest *request = mRequestList->first(); request;)
00273 {
00274 if (!cookiesPending( request->url ))
00275 {
00276 QCString replyType;
00277 QByteArray replyData;
00278 QString res = mCookieJar->findCookies( request->url, request->DOM, request->windowId );
00279
00280 QDataStream stream2(replyData, IO_WriteOnly);
00281 stream2 << res;
00282 replyType = "QString";
00283 request->client->endTransaction( request->transaction,
00284 replyType, replyData);
00285 CookieRequest *tmp = request;
00286 request = mRequestList->next();
00287 mRequestList->removeRef( tmp );
00288 delete tmp;
00289 }
00290 else
00291 {
00292 request = mRequestList->next();
00293 }
00294 }
00295 if (mCookieJar->changed() && !mTimer)
00296 saveCookieJar();
00297 }
00298
00299 void KCookieServer::slotSave()
00300 {
00301 delete mTimer;
00302 mTimer = 0;
00303 QString filename = locateLocal("data", "kcookiejar/cookies");
00304 mCookieJar->saveCookies(filename);
00305 }
00306
00307 void KCookieServer::saveCookieJar()
00308 {
00309 if( mTimer )
00310 return;
00311
00312 mTimer = new QTimer();
00313 connect( mTimer, SIGNAL( timeout()), SLOT( slotSave()));
00314 mTimer->start( 1000*60*SAVE_DELAY );
00315 }
00316
00317 void KCookieServer::putCookie( QStringList& out, KHttpCookie *cookie,
00318 const QValueList<int>& fields )
00319 {
00320 QValueList<int>::ConstIterator i = fields.begin();
00321 for ( ; i != fields.end(); ++i )
00322 {
00323 switch(*i)
00324 {
00325 case CF_DOMAIN :
00326 out << cookie->domain();
00327 break;
00328 case CF_NAME :
00329 out << cookie->name();
00330 break;
00331 case CF_PATH :
00332 out << cookie->path();
00333 break;
00334 case CF_HOST :
00335 out << cookie->host();
00336 break;
00337 case CF_VALUE :
00338 out << cookie->value();
00339 break;
00340 case CF_EXPIRE :
00341 out << QString::number(cookie->expireDate());
00342 break;
00343 case CF_PROVER :
00344 out << QString::number(cookie->protocolVersion());
00345 break;
00346 case CF_SECURE :
00347 out << QString::number( cookie->isSecure() ? 1 : 0 );
00348 break;
00349 default :
00350 out << QString::null;
00351 }
00352 }
00353 }
00354
00355 bool KCookieServer::cookieMatches( KHttpCookiePtr c,
00356 QString domain, QString fqdn,
00357 QString path, QString name )
00358 {
00359 if( c )
00360 {
00361 bool hasDomain = !domain.isEmpty();
00362 return
00363 ((hasDomain && c->domain() == domain) ||
00364 fqdn == c->host()) &&
00365 (c->path() == path) &&
00366 (c->name() == name) &&
00367 (!c->isExpired(time(0)));
00368 }
00369 return false;
00370 }
00371
00372
00373 QString
00374 KCookieServer::findCookies(QString url)
00375 {
00376 return findCookies(url, 0);
00377 }
00378
00379
00380 QString
00381 KCookieServer::findCookies(QString url, long windowId)
00382 {
00383 if (cookiesPending(url))
00384 {
00385 CookieRequest *request = new CookieRequest;
00386 request->client = callingDcopClient();
00387 request->transaction = request->client->beginTransaction();
00388 request->url = url;
00389 request->DOM = false;
00390 request->windowId = windowId;
00391 mRequestList->append( request );
00392 return QString::null;
00393 }
00394
00395 QString cookies = mCookieJar->findCookies(url, false, windowId);
00396
00397 if (mCookieJar->changed() && !mTimer)
00398 saveCookieJar();
00399
00400 return cookies;
00401 }
00402
00403
00404 QStringList
00405 KCookieServer::findDomains()
00406 {
00407 QStringList result;
00408 const QStringList domains = mCookieJar->getDomainList();
00409 for ( QStringList::ConstIterator domIt = domains.begin();
00410 domIt != domains.end(); ++domIt )
00411 {
00412
00413
00414 const KHttpCookieList* list = mCookieJar->getCookieList(*domIt, "");
00415 if ( list && !list->isEmpty() )
00416 result << *domIt;
00417 }
00418 return result;
00419 }
00420
00421
00422 QStringList
00423 KCookieServer::findCookies(QValueList<int> fields,
00424 QString domain,
00425 QString fqdn,
00426 QString path,
00427 QString name)
00428 {
00429 QStringList result;
00430 bool allDomCookies = name.isEmpty();
00431
00432 const KHttpCookieList* list = mCookieJar->getCookieList(domain, fqdn);
00433 if ( list && !list->isEmpty() )
00434 {
00435 QPtrListIterator<KHttpCookie>it( *list );
00436 for ( ; it.current(); ++it )
00437 {
00438 if ( !allDomCookies )
00439 {
00440 if ( cookieMatches(it.current(), domain, fqdn, path, name) )
00441 {
00442 putCookie(result, it.current(), fields);
00443 break;
00444 }
00445 }
00446 else
00447 putCookie(result, it.current(), fields);
00448 }
00449 }
00450 return result;
00451 }
00452
00453
00454 QString
00455 KCookieServer::findDOMCookies(QString url)
00456 {
00457 return findDOMCookies(url, 0);
00458 }
00459
00460
00461 QString
00462 KCookieServer::findDOMCookies(QString url, long windowId)
00463 {
00464
00465
00466
00467 KHttpCookieList pendingCookies;
00468 cookiesPending(url, &pendingCookies);
00469
00470 return mCookieJar->findCookies(url, true, windowId, &pendingCookies);
00471 }
00472
00473
00474 void
00475 KCookieServer::addCookies(QString arg1, QCString arg2, long arg3)
00476 {
00477 addCookies(arg1, arg2, arg3, false);
00478 }
00479
00480
00481 void
00482 KCookieServer::deleteCookie(QString domain, QString fqdn,
00483 QString path, QString name)
00484 {
00485 const KHttpCookieList* list = mCookieJar->getCookieList( domain, fqdn );
00486 if ( list && !list->isEmpty() )
00487 {
00488 QPtrListIterator<KHttpCookie>it (*list);
00489 for ( ; it.current(); ++it )
00490 {
00491 if( cookieMatches(it.current(), domain, fqdn, path, name) )
00492 {
00493 mCookieJar->eatCookie( it.current() );
00494 if (!mTimer)
00495 saveCookieJar();
00496 break;
00497 }
00498 }
00499 }
00500 }
00501
00502
00503 void
00504 KCookieServer::deleteCookiesFromDomain(QString domain)
00505 {
00506 mCookieJar->eatCookiesForDomain(domain);
00507 if (!mTimer)
00508 saveCookieJar();
00509 }
00510
00511
00512
00513 void
00514 KCookieServer::slotDeleteSessionCookies( long windowId )
00515 {
00516 deleteSessionCookies(windowId);
00517 }
00518
00519
00520 void
00521 KCookieServer::deleteSessionCookies( long windowId )
00522 {
00523 mCookieJar->eatSessionCookies( windowId );
00524 if(!mTimer)
00525 saveCookieJar();
00526 }
00527
00528 void
00529 KCookieServer::deleteSessionCookiesFor(QString fqdn, long windowId)
00530 {
00531 mCookieJar->eatSessionCookies( fqdn, windowId );
00532 if(!mTimer)
00533 saveCookieJar();
00534 }
00535
00536
00537 void
00538 KCookieServer::deleteAllCookies()
00539 {
00540 mCookieJar->eatAllCookies();
00541 if (!mTimer)
00542 saveCookieJar();
00543 }
00544
00545
00546 void
00547 KCookieServer::addDOMCookies(QString arg1, QCString arg2, long arg3)
00548 {
00549 addCookies(arg1, arg2, arg3, true);
00550 }
00551
00552
00553 void
00554 KCookieServer::setDomainAdvice(QString url, QString advice)
00555 {
00556 QString fqdn;
00557 QString dummy;
00558 if (KCookieJar::parseURL(url, fqdn, dummy))
00559 {
00560 QStringList domains;
00561 mCookieJar->extractDomains(fqdn, domains);
00562
00563 mCookieJar->setDomainAdvice(domains[domains.count() > 3 ? 3 : 0],
00564 KCookieJar::strToAdvice(advice));
00565
00566 mCookieJar->saveConfig( mConfig );
00567 }
00568 }
00569
00570
00571 QString
00572 KCookieServer::getDomainAdvice(QString url)
00573 {
00574 KCookieAdvice advice = KCookieDunno;
00575 QString fqdn;
00576 QString dummy;
00577 if (KCookieJar::parseURL(url, fqdn, dummy))
00578 {
00579 QStringList domains;
00580 mCookieJar->extractDomains(fqdn, domains);
00581
00582 QStringList::ConstIterator it = domains.begin();
00583 while ( (advice == KCookieDunno) && (it != domains.end()) )
00584 {
00585
00586
00587
00588 if ( (*it)[0] == '.' || (*it) == fqdn )
00589 advice = mCookieJar->getDomainAdvice(*it);
00590 ++it;
00591 }
00592 if (advice == KCookieDunno)
00593 advice = mCookieJar->getGlobalAdvice();
00594 }
00595 return KCookieJar::adviceToStr(advice);
00596 }
00597
00598
00599 void
00600 KCookieServer::reloadPolicy()
00601 {
00602 mCookieJar->loadConfig( mConfig, true );
00603 }
00604
00605
00606 void
00607 KCookieServer::shutdown()
00608 {
00609 deleteLater();
00610 }
00611
00612 #include "kcookieserver.moc"
00613