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 #include "tcpslavebase.h"
00027
00028 #include <config.h>
00029
00030 #include <sys/types.h>
00031 #include <sys/uio.h>
00032 #include <sys/time.h>
00033 #include <sys/socket.h>
00034
00035 #include <netinet/in.h>
00036
00037 #include <time.h>
00038 #include <netdb.h>
00039 #include <unistd.h>
00040 #include <errno.h>
00041
00042 #include <kdebug.h>
00043 #include <ksslcertificatemanager.h>
00044 #include <ksslsettings.h>
00045 #include <kmessagebox.h>
00046 #include <network/ktcpsocket.h>
00047
00048 #include <klocale.h>
00049 #include <QtCore/QDataStream>
00050 #include <QtCore/QTime>
00051 #include <QtNetwork/QTcpSocket>
00052 #include <QtNetwork/QHostInfo>
00053 #include <QtDBus/QtDBus>
00054
00055 #include <kapplication.h>
00056 #include <ktoolinvocation.h>
00057 #include <ksocketfactory.h>
00058 #include <kprotocolmanager.h>
00059
00060 using namespace KIO;
00061
00062
00063 typedef QMap<QString, QString> StringStringMap;
00064 Q_DECLARE_METATYPE(StringStringMap)
00065
00066 namespace KIO {
00067 Q_DECLARE_OPERATORS_FOR_FLAGS(TCPSlaveBase::SslResult)
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00103 class TCPSlaveBase::TcpSlaveBasePrivate
00104 {
00105 public:
00106 QList<KSslError> nonIgnorableErrors(const QList<KSslError> &) const
00107 {
00108 QList<KSslError> ret;
00109
00110 return ret;
00111 }
00112
00113 int timeout;
00114 bool isBlocking;
00115
00116 KTcpSocket socket;
00117
00118 QString host;
00119 QString ip;
00120 quint16 port;
00121 QByteArray serviceName;
00122
00123 KSSLSettings sslSettings;
00124 bool usingSSL;
00125 bool autoSSL;
00126 bool sslNoUi;
00127
00128 };
00129
00130
00131
00132 QIODevice *TCPSlaveBase::socket() const
00133 {
00134 return &d->socket;
00135 }
00136
00137
00138 TCPSlaveBase::TCPSlaveBase(const QByteArray &protocol,
00139 const QByteArray &poolSocket,
00140 const QByteArray &appSocket,
00141 bool autoSSL)
00142 : SlaveBase(protocol, poolSocket, appSocket),
00143 d(new TcpSlaveBasePrivate)
00144 {
00145 d->timeout = KProtocolManager::connectTimeout();
00146 d->isBlocking = true;
00147 d->port = 0;
00148 d->serviceName = protocol;
00149 d->usingSSL = false;
00150 d->autoSSL = autoSSL;
00151 d->sslNoUi = false;
00152 }
00153
00154
00155 TCPSlaveBase::~TCPSlaveBase()
00156 {
00157 delete d;
00158 }
00159
00160
00161 ssize_t TCPSlaveBase::write(const char *data, ssize_t len)
00162 {
00163 ssize_t written = d->socket.write(data, len);
00164 if (written == -1) {
00165 kDebug(7027) << "d->socket.write() returned -1! Socket error is"
00166 << d->socket.error() << ", Socket state is" << d->socket.state();
00167 }
00168
00169 bool success = false;
00170 if (d->isBlocking) {
00171
00172 success = d->socket.waitForBytesWritten(-1);
00173 } else {
00174
00175
00176
00177 success = d->socket.waitForBytesWritten(0);
00178 }
00179
00180 if (d->socket.state() != KTcpSocket::ConnectedState || !success) {
00181 kDebug(7027) << "Write failed, will return -1! Socket error is"
00182 << d->socket.error() << ", Socket state is" << d->socket.state()
00183 << "Return value of waitForBytesWritten() is" << success;
00184 return -1;
00185 }
00186
00187 return written;
00188 }
00189
00190
00191 ssize_t TCPSlaveBase::read(char* data, ssize_t len)
00192 {
00193 if (d->usingSSL && (d->socket.encryptionMode() != KTcpSocket::SslClientMode)) {
00194 setMetaData("ssl_in_use", "FALSE");
00195 kDebug(7029) << "lost SSL connection.";
00196 return -1;
00197 }
00198
00199 if (!d->socket.bytesAvailable()) {
00200 if (d->isBlocking) {
00201 d->socket.waitForReadyRead(-1);
00202 } else {
00203 d->socket.waitForReadyRead(0);
00204 }
00205 }
00206
00207 return d->socket.read(data, len);
00208 }
00209
00210
00211 ssize_t TCPSlaveBase::readLine(char *data, ssize_t len)
00212 {
00213 if (d->usingSSL && (d->socket.encryptionMode() != KTcpSocket::SslClientMode)) {
00214 setMetaData("ssl_in_use", "FALSE");
00215 kDebug(7029) << "lost SSL connection.";
00216 return -1;
00217 }
00218
00219
00220
00221
00222 #ifdef PIGS_CAN_FLY
00223 if (!d->isBlocking) {
00224 d->socket.waitForReadyRead(0);
00225 return d->socket.readLine(data, len);
00226 }
00227 #endif
00228 ssize_t readTotal = 0;
00229 do {
00230 if (!d->socket.bytesAvailable())
00231 d->socket.waitForReadyRead(-1);
00232 ssize_t readStep = d->socket.readLine(&data[readTotal], len-readTotal);
00233 if (readStep == -1) {
00234 return -1;
00235 }
00236 readTotal += readStep;
00237 } while (readTotal == 0 || data[readTotal-1] != '\n');
00238
00239 return readTotal;
00240 }
00241
00242
00243 bool TCPSlaveBase::connectToHost(const QString &,
00244 const QString &host,
00245 quint16 port)
00246 {
00247 setMetaData("ssl_in_use", "FALSE");
00248
00249
00250
00251
00252 if (metaData("main_frame_request") == "TRUE"
00253 && metaData("ssl_activate_warnings") == "TRUE"
00254 && metaData("ssl_was_in_use") == "TRUE"
00255 && !d->autoSSL) {
00256 KSSLSettings kss;
00257 if (kss.warnOnLeave()) {
00258 int result = messageBox(i18n("You are about to leave secure "
00259 "mode. Transmissions will no "
00260 "longer be encrypted.\nThis "
00261 "means that a third party could "
00262 "observe your data in transit."),
00263 WarningContinueCancel,
00264 i18n("Security Information"),
00265 i18n("C&ontinue Loading"), QString(),
00266 "WarnOnLeaveSSLMode");
00267
00268 if (result == KMessageBox::Cancel) {
00269 return false;
00270 }
00271 }
00272 }
00273
00274 KTcpSocket::SslVersion trySslVersion = KTcpSocket::TlsV1;
00275 while (true) {
00276 disconnectFromHost();
00277 d->host = host;
00278
00279
00280
00281 QList<QHostAddress> addresses;
00282
00283 QHostAddress address;
00284 if (address.setAddress(host)) {
00285 addresses.append(address);
00286 } else {
00287 QHostInfo info;
00288 lookupHost(host);
00289 waitForHostInfo(info);
00290 if (info.error() != QHostInfo::NoError) {
00291 error(ERR_UNKNOWN_HOST, host);
00292 return false;
00293 }
00294 addresses = info.addresses();
00295 }
00296
00297 QListIterator<QHostAddress> it(addresses);
00298 int timeout = d->timeout * 1000;
00299 QTime time;
00300 forever {
00301 time.start();
00302 d->socket.connectToHost(it.next(), port);
00303 if (d->socket.waitForConnected(timeout)) {
00304 break;
00305 }
00306 timeout -= time.elapsed();
00307 if (!it.hasNext() || (timeout < 0)) {
00308 error(ERR_COULD_NOT_CONNECT,
00309 host + QLatin1String(": ") + d->socket.errorString());
00310 return false;
00311 }
00312 }
00313
00314
00315
00316 d->ip = d->socket.peerAddress().toString();
00317 d->port = d->socket.peerPort();
00318
00319 if (d->autoSSL) {
00320 SslResult res = startTLSInternal(trySslVersion);
00321 if ((res & ResultFailed) && (res & ResultFailedEarly)
00322 && (trySslVersion == KTcpSocket::TlsV1)) {
00323 trySslVersion = KTcpSocket::SslV3;
00324 continue;
00325
00326 }
00327 if (res & ResultFailed) {
00328 error(ERR_COULD_NOT_CONNECT,
00329 i18nc("%1 is a host name", "%1: SSL negotiation failed", host));
00330 return false;
00331 }
00332 }
00333 return true;
00334 }
00335 Q_ASSERT(false);
00336 }
00337
00338 void TCPSlaveBase::disconnectFromHost()
00339 {
00340 kDebug(7027);
00341 d->host.clear();
00342 d->ip.clear();
00343 d->usingSSL = false;
00344
00345 if (d->socket.state() == KTcpSocket::UnconnectedState) {
00346
00347
00348 d->socket.close();
00349 return;
00350 }
00351
00352
00353
00354
00355 d->socket.disconnectFromHost();
00356 if (d->socket.state() != KTcpSocket::UnconnectedState)
00357 d->socket.waitForDisconnected(-1);
00358 d->socket.close();
00359 }
00360
00361 bool TCPSlaveBase::isAutoSsl() const
00362 {
00363 return d->autoSSL;
00364 }
00365
00366 bool TCPSlaveBase::isUsingSsl() const
00367 {
00368 return d->usingSSL;
00369 }
00370
00371 quint16 TCPSlaveBase::port() const
00372 {
00373 return d->port;
00374 }
00375
00376 bool TCPSlaveBase::atEnd() const
00377 {
00378 return d->socket.atEnd();
00379 }
00380
00381 bool TCPSlaveBase::startSsl()
00382 {
00383 if (d->usingSSL)
00384 return false;
00385 return startTLSInternal(KTcpSocket::TlsV1) & ResultOk;
00386 }
00387
00388
00389 TCPSlaveBase::SslResult TCPSlaveBase::startTLSInternal(uint v_)
00390 {
00391 KTcpSocket::SslVersion sslVersion = static_cast<KTcpSocket::SslVersion>(v_);
00392 selectClientCertificate();
00393
00394
00395
00396
00397 d->usingSSL = true;
00398 setMetaData("ssl_in_use", "TRUE");
00399
00400 d->socket.setAdvertisedSslVersion(sslVersion);
00401
00402
00403
00404
00405
00406 d->socket.ignoreSslErrors();
00407 d->socket.startClientEncryption();
00408 const bool encryptionStarted = d->socket.waitForEncrypted(-1);
00409
00410
00411 KSslCipher cipher = d->socket.sessionCipher();
00412
00413 if (!encryptionStarted || d->socket.encryptionMode() != KTcpSocket::SslClientMode
00414 || cipher.isNull() || cipher.usedBits() == 0) {
00415
00416 d->usingSSL = false;
00417 setMetaData("ssl_in_use", "FALSE");
00418 kDebug(7029) << "Initial SSL handshake failed. encryptionStarted is"
00419 << encryptionStarted << ", cipher.isNull() is" << cipher.isNull()
00420 << ", cipher.usedBits() is" << cipher.usedBits()
00421 << ", the socket says:" << d->socket.errorString()
00422 << "and the list of SSL errors contains"
00423 << d->socket.sslErrors().count() << "items.";
00424 return ResultFailed | ResultFailedEarly;
00425 }
00426
00427 kDebug(7029) << "Cipher info - "
00428 << " advertised SSL protocol version" << d->socket.advertisedSslVersion()
00429 << " negotiated SSL protocol version" << d->socket.negotiatedSslVersion()
00430 << " authenticationMethod:" << cipher.authenticationMethod()
00431 << " encryptionMethod:" << cipher.encryptionMethod()
00432 << " keyExchangeMethod:" << cipher.keyExchangeMethod()
00433 << " name:" << cipher.name()
00434 << " supportedBits:" << cipher.supportedBits()
00435 << " usedBits:" << cipher.usedBits();
00436
00437 setMetaData("ssl_protocol_version", d->socket.negotiatedSslVersionName());
00438 QString sslCipher = cipher.encryptionMethod() + '\n';
00439 sslCipher += cipher.authenticationMethod() + '\n';
00440 sslCipher += cipher.keyExchangeMethod() + '\n';
00441 sslCipher += cipher.digestMethod();
00442 setMetaData("ssl_cipher", sslCipher);
00443 setMetaData("ssl_cipher_used_bits", QString::number(cipher.usedBits()));
00444 setMetaData("ssl_cipher_bits", QString::number(cipher.supportedBits()));
00445 setMetaData("ssl_peer_ip", d->ip);
00446
00447
00448
00449 QList<KSslError> sslErrors = d->socket.sslErrors();
00450 for (int i = 0; i < sslErrors.count(); i++) {
00451 if (sslErrors[i].certificate().isNull()) {
00452 sslErrors[i] = KSslError(sslErrors[i].error(),
00453 d->socket.peerCertificateChain()[0]);
00454 }
00455 }
00456
00457 QString errorStr;
00458
00459 foreach (const QSslCertificate &cert, d->socket.peerCertificateChain()) {
00460 foreach (const KSslError &error, sslErrors) {
00461 if (error.certificate() == cert) {
00462 errorStr += QString::number(static_cast<int>(error.error())) + '\t';
00463 }
00464 }
00465 if (errorStr.endsWith('\t')) {
00466 errorStr.chop(1);
00467 }
00468 errorStr += '\n';
00469 }
00470 errorStr.chop(1);
00471 setMetaData("ssl_cert_errors", errorStr);
00472
00473 QString peerCertChain;
00474 foreach (const QSslCertificate &cert, d->socket.peerCertificateChain()) {
00475 peerCertChain.append(cert.toPem());
00476 peerCertChain.append('\x01');
00477 }
00478 peerCertChain.chop(1);
00479 setMetaData("ssl_peer_chain", peerCertChain);
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 sendAndKeepMetaData();
00490
00491 SslResult rc = verifyServerCertificate();
00492 if (rc & ResultFailed) {
00493 d->usingSSL = false;
00494 setMetaData("ssl_in_use", "FALSE");
00495 kDebug(7029) << "server certificate verification failed.";
00496 d->socket.disconnectFromHost();
00497 return ResultFailed;
00498 } else if (rc & ResultOverridden) {
00499 kDebug(7029) << "server certificate verification failed but continuing at user's request.";
00500 }
00501
00502
00503 if (metaData("ssl_activate_warnings") == "TRUE"
00504 && metaData("ssl_was_in_use") == "FALSE"
00505 && d->sslSettings.warnOnEnter()) {
00506
00507 int msgResult = messageBox(i18n("You are about to enter secure mode. "
00508 "All transmissions will be encrypted "
00509 "unless otherwise noted.\nThis means "
00510 "that no third party will be able to "
00511 "easily observe your data in transit."),
00512 WarningYesNo,
00513 i18n("Security Information"),
00514 i18n("Display SSL &Information"),
00515 i18n("C&onnect"),
00516 "WarnOnEnterSSLMode");
00517 if (msgResult == KMessageBox::Yes) {
00518 messageBox(SSLMessageBox , d->host);
00519 }
00520 }
00521
00522 return rc;
00523 }
00524
00525
00526 void TCPSlaveBase::selectClientCertificate()
00527 {
00528 #if 0 //hehe
00529 QString certname;
00530 bool send = false, prompt = false, save = false, forcePrompt = false;
00531 KSSLCertificateHome::KSSLAuthAction aa;
00532
00533 setMetaData("ssl_using_client_cert", "FALSE");
00534
00535 if (metaData("ssl_no_client_cert") == "TRUE") return;
00536 forcePrompt = (metaData("ssl_force_cert_prompt") == "TRUE");
00537
00538
00539 if (d->pkcs) {
00540 delete d->pkcs;
00541 d->pkcs = NULL;
00542 }
00543
00544 if (!d->kssl) return;
00545
00546
00547 if (!forcePrompt) {
00548 certname = KSSLCertificateHome::getDefaultCertificateName(&aa);
00549 switch (aa) {
00550 case KSSLCertificateHome::AuthSend:
00551 send = true; prompt = false;
00552 break;
00553 case KSSLCertificateHome::AuthDont:
00554 send = false; prompt = false;
00555 certname.clear();
00556 break;
00557 case KSSLCertificateHome::AuthPrompt:
00558 send = false; prompt = true;
00559 break;
00560 default:
00561 break;
00562 }
00563 }
00564
00565
00566 QString tmpcn = KSSLCertificateHome::getDefaultCertificateName(d->host, &aa);
00567 if (aa != KSSLCertificateHome::AuthNone) {
00568 switch (aa) {
00569 case KSSLCertificateHome::AuthSend:
00570 send = true;
00571 prompt = false;
00572 certname = tmpcn;
00573 break;
00574 case KSSLCertificateHome::AuthDont:
00575 send = false;
00576 prompt = false;
00577 certname.clear();
00578 break;
00579 case KSSLCertificateHome::AuthPrompt:
00580 send = false;
00581 prompt = true;
00582 certname = tmpcn;
00583 break;
00584 default:
00585 break;
00586 }
00587 }
00588
00589
00590 if (hasMetaData("ssl_demand_certificate")) {
00591 certname = metaData("ssl_demand_certificate");
00592 if (!certname.isEmpty()) {
00593 forcePrompt = false;
00594 prompt = false;
00595 send = true;
00596 }
00597 }
00598
00599 if (certname.isEmpty() && !prompt && !forcePrompt) return;
00600
00601
00602 if (prompt || forcePrompt) {
00603 QStringList certs = KSSLCertificateHome::getCertificateList();
00604
00605 QStringList::const_iterator it = certs.begin();
00606 while (it != certs.end()) {
00607 KSSLPKCS12 *pkcs = KSSLCertificateHome::getCertificateByName(*it);
00608 if (pkcs && (!pkcs->getCertificate() ||
00609 !pkcs->getCertificate()->x509V3Extensions().certTypeSSLClient())) {
00610 it = certs.erase(it);
00611 } else {
00612 ++it;
00613 }
00614 delete pkcs;
00615 }
00616
00617 if (certs.isEmpty()) return;
00618
00619 if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kio.uiserver")) {
00620 KToolInvocation::startServiceByDesktopPath("kuiserver.desktop",
00621 QStringList());
00622 }
00623
00624 QDBusInterface uis("org.kde.kio.uiserver", "/UIServer", "org.kde.KIO.UIServer");
00625
00626 QDBusMessage retVal = uis.call("showSSLCertDialog", d->host, certs, metaData("window-id").toLongLong());
00627 if (retVal.type() == QDBusMessage::ReplyMessage) {
00628 if (retVal.arguments().at(0).toBool()) {
00629 send = retVal.arguments().at(1).toBool();
00630 save = retVal.arguments().at(2).toBool();
00631 certname = retVal.arguments().at(3).toString();
00632 }
00633 }
00634 }
00635
00636
00637
00638 if (!send) {
00639 if (save) {
00640 KSSLCertificateHome::setDefaultCertificate(certname, d->host,
00641 false, false);
00642 }
00643 return;
00644 }
00645
00646
00647 KSSLPKCS12 *pkcs = KSSLCertificateHome::getCertificateByName(certname);
00648 if (!pkcs && KSSLCertificateHome::hasCertificateByName(certname)) {
00649 KIO::AuthInfo ai;
00650 bool first = true;
00651 do {
00652 ai.prompt = i18n("Enter the certificate password:");
00653 ai.caption = i18n("SSL Certificate Password");
00654 ai.url.setProtocol("kssl");
00655 ai.url.setHost(certname);
00656 ai.username = certname;
00657 ai.keepPassword = true;
00658
00659 bool showprompt;
00660 if (first)
00661 showprompt = !checkCachedAuthentication(ai);
00662 else
00663 showprompt = true;
00664 if (showprompt) {
00665 if (!openPasswordDialog(ai, first ? QString() :
00666 i18n("Unable to open the certificate. Try a new password?")))
00667 break;
00668 }
00669
00670 first = false;
00671 pkcs = KSSLCertificateHome::getCertificateByName(certname, ai.password);
00672 } while (!pkcs);
00673
00674 }
00675
00676
00677 if (pkcs) {
00678 if (!d->kssl->setClientCertificate(pkcs)) {
00679 messageBox(Information, i18n("The procedure to set the "
00680 "client certificate for the session "
00681 "failed."), i18n("SSL"));
00682 delete pkcs;
00683 pkcs = 0L;
00684 } else {
00685 kDebug(7029) << "Client SSL certificate is being used.";
00686 setMetaData("ssl_using_client_cert", "TRUE");
00687 if (save) {
00688 KSSLCertificateHome::setDefaultCertificate(certname, d->host,
00689 true, false);
00690 }
00691 }
00692 d->pkcs = pkcs;
00693 }
00694 #endif
00695 }
00696
00697
00698 TCPSlaveBase::SslResult TCPSlaveBase::verifyServerCertificate()
00699 {
00700 d->sslNoUi = hasMetaData("ssl_no_ui") && (metaData("ssl_no_ui") != "FALSE");
00701
00702 QList<KSslError> se = d->socket.sslErrors();
00703 if (se.isEmpty())
00704 return ResultOk;
00705
00706
00707
00708
00709
00710 QSslCertificate peerCert = d->socket.peerCertificateChain().first();
00711 QStringList domainPatterns(peerCert.subjectInfo(QSslCertificate::CommonName));
00712 domainPatterns += peerCert.alternateSubjectNames().values(QSsl::DnsEntry);
00713 QRegExp domainMatcher(QString(), Qt::CaseInsensitive, QRegExp::Wildcard);
00714 QMutableListIterator<KSslError> it(se);
00715 while (it.hasNext()) {
00716
00717
00718
00719
00720 if (it.next().error() != KSslError::HostNameMismatch) {
00721 continue;
00722 }
00723 foreach (const QString &dp, domainPatterns) {
00724 domainMatcher.setPattern(dp);
00725 if (domainMatcher.exactMatch(d->host)) {
00726 it.remove();
00727 }
00728 }
00729 }
00730
00731 if (se.isEmpty())
00732 return ResultOk;
00733
00734 if (d->sslNoUi)
00735 return ResultFailed;
00736
00737 QString message = i18n("The server failed the authenticity check (%1).\n\n",
00738 d->host);
00739
00740 foreach (const KSslError &err, se) {
00741
00742 message.append(err.errorString());
00743 message.append('\n');
00744 }
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760 KSslCertificateManager *const cm = KSslCertificateManager::self();
00761 KSslCertificateRule rule = cm->rule(d->socket.peerCertificateChain().first(), d->host);
00762
00763
00764 QList<KSslError> fatalErrors = d->nonIgnorableErrors(se);
00765 if (!fatalErrors.isEmpty()) {
00766
00767 return ResultFailed;
00768 }
00769
00770
00771 se = rule.filterErrors(se);
00772 if (se.isEmpty()) {
00773 kDebug(7029) << "Error list empty after removing errors to be ignored. Continuing.";
00774 return ResultOk | ResultOverridden;
00775 }
00776
00777
00778
00779
00780 int msgResult;
00781 do {
00782 msgResult = messageBox(WarningYesNoCancel, message.trimmed(),
00783 i18n("Server Authentication"),
00784 i18n("&Details"), i18n("Co&ntinue"));
00785 if (msgResult == KMessageBox::Yes) {
00786
00787 messageBox(SSLMessageBox , d->host);
00788 } else if (msgResult == KMessageBox::Cancel) {
00789 return ResultFailed;
00790 }
00791
00792 } while (msgResult == KMessageBox::Yes);
00793
00794
00795
00796 msgResult = messageBox(WarningYesNo,
00797 i18n("Would you like to accept this "
00798 "certificate forever without "
00799 "being prompted?"),
00800 i18n("Server Authentication"),
00801 i18n("&Forever"),
00802 i18n("&Current Sessions Only"));
00803 QDateTime ruleExpiry = QDateTime::currentDateTime();
00804 if (msgResult == KMessageBox::Yes) {
00805
00806 ruleExpiry = ruleExpiry.addYears(1000);
00807 } else {
00808
00809 ruleExpiry = ruleExpiry.addSecs(30*60);
00810 }
00811
00812
00813
00814
00815 rule.setExpiryDateTime(ruleExpiry);
00816 rule.setIgnoredErrors(se);
00817 cm->setRule(rule);
00818
00819 return ResultOk | ResultOverridden;
00820 #if 0 //### need to to do something like the old code about the main and subframe stuff
00821 kDebug(7029) << "SSL HTTP frame the parent? " << metaData("main_frame_request");
00822 if (!hasMetaData("main_frame_request") || metaData("main_frame_request") == "TRUE") {
00823
00824 setMetaData("ssl_parent_ip", d->ip);
00825 setMetaData("ssl_parent_cert", pc.toString());
00826
00827 KSSLCertificateCache::KSSLCertificatePolicy cp =
00828 d->certCache->getPolicyByCertificate(pc);
00829
00830
00831 if (ksv != KSSLCertificate::Ok) {
00832 if (d->sslNoUi) {
00833 return -1;
00834 }
00835
00836 if (cp == KSSLCertificateCache::Unknown ||
00837 cp == KSSLCertificateCache::Ambiguous) {
00838 cp = KSSLCertificateCache::Prompt;
00839 } else {
00840
00841 permacache = d->certCache->isPermanent(pc);
00842 }
00843
00844 if (!_IPmatchesCN && cp == KSSLCertificateCache::Accept) {
00845 cp = KSSLCertificateCache::Prompt;
00846
00847 }
00848
00850
00851
00852 d->certCache->addCertificate(pc, cp, permacache);
00853 if (doAddHost) d->certCache->addHost(pc, d->host);
00854 } else {
00855
00856 KSSLCertificateCache::KSSLCertificatePolicy cp =
00857 d->certCache->getPolicyByCertificate(pc);
00858 isChild = true;
00859
00860
00861
00862 bool certAndIPTheSame = (d->ip == metaData("ssl_parent_ip") &&
00863 pc.toString() == metaData("ssl_parent_cert"));
00864
00865 if (ksv == KSSLCertificate::Ok) {
00866 if (certAndIPTheSame) {
00867 rc = 1;
00868 setMetaData("ssl_action", "accept");
00869 } else {
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885 setMetaData("ssl_action", "accept");
00886 rc = 1;
00887
00888
00889 }
00890 } else {
00891 if (d->sslNoUi) {
00892 return -1;
00893 }
00894
00895 if (cp == KSSLCertificateCache::Accept) {
00896 if (certAndIPTheSame) {
00897 rc = 1;
00898 setMetaData("ssl_action", "accept");
00899 } else {
00900 result = messageBox(WarningYesNo,
00901 i18n("You have indicated that you wish to accept this certificate, but it is not issued to the server who is presenting it. Do you wish to continue loading?"),
00902 i18n("Server Authentication"));
00903 if (result == KMessageBox::Yes) {
00904 rc = 1;
00905 setMetaData("ssl_action", "accept");
00906 d->certCache->addHost(pc, d->host);
00907 } else {
00908 rc = -1;
00909 setMetaData("ssl_action", "reject");
00910 }
00911 }
00912 } else if (cp == KSSLCertificateCache::Reject) {
00913 messageBox(Information, i18n("SSL certificate is being rejected as requested. You can disable this in the KDE Control Center."),
00914 i18n("Server Authentication"));
00915 rc = -1;
00916 setMetaData("ssl_action", "reject");
00917 } else {
00918
00920
00921 return rc;
00922 #endif //#if 0
00923 return ResultOk | ResultOverridden;
00924 }
00925
00926
00927 bool TCPSlaveBase::isConnected() const
00928 {
00929
00930 return d->socket.state() == KTcpSocket::ConnectedState;
00931 }
00932
00933
00934 bool TCPSlaveBase::waitForResponse(int t)
00935 {
00936 if (d->socket.bytesAvailable()) {
00937 return true;
00938 }
00939 return d->socket.waitForReadyRead(t * 1000);
00940 }
00941
00942 void TCPSlaveBase::setBlocking(bool b)
00943 {
00944 if (!b) {
00945 kWarning(7029) << "Caller requested non-blocking mode, but that doesn't work";
00946 return;
00947 }
00948 d->isBlocking = b;
00949 }
00950
00951 void TCPSlaveBase::virtual_hook(int id, void* data)
00952 {
00953 SlaveBase::virtual_hook(id, data);
00954 }
00955
00956