• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KIO

  • kio
  • kio
tcpslavebase.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2000 Alex Zepeda <zipzippy@sonic.net>
3 * Copyright (C) 2001-2003 George Staikos <staikos@kde.org>
4 * Copyright (C) 2001 Dawit Alemayehu <adawit@kde.org>
5 * Copyright (C) 2007,2008 Andreas Hartmetz <ahartmetz@gmail.com>
6 * Copyright (C) 2008 Roland Harnau <tau@gmx.eu>
7 * Copyright (C) 2010 Richard Moore <rich@kde.org>
8 *
9 * This file is part of the KDE project
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Library General Public
13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Library General Public License for more details.
20 *
21 * You should have received a copy of the GNU Library General Public License
22 * along with this library; see the file COPYING.LIB. If not, write to
23 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 * Boston, MA 02110-1301, USA.
25 */
26
27#include "tcpslavebase.h"
28
29#include <config.h>
30
31#include <kdebug.h>
32#include <kconfiggroup.h>
33#include <ksslcertificatemanager.h>
34#include <ksslsettings.h>
35#include <kmessagebox.h>
36#include <klocale.h>
37#include <ktoolinvocation.h>
38#include <network/ktcpsocket.h>
39
40#include <QtCore/QDataStream>
41#include <QtCore/QTime>
42#include <QtNetwork/QTcpSocket>
43#include <QtNetwork/QHostInfo>
44#include <QtNetwork/QSslConfiguration>
45#include <QtDBus/QtDBus>
46
47
48using namespace KIO;
49//using namespace KNetwork;
50
51typedef QMap<QString, QString> StringStringMap;
52Q_DECLARE_METATYPE(StringStringMap)
53
54namespace KIO {
55Q_DECLARE_OPERATORS_FOR_FLAGS(TCPSlaveBase::SslResult)
56}
57
58//TODO Proxy support whichever way works; KPAC reportedly does *not* work.
59//NOTE kded_proxyscout may or may not be interesting
60
61//TODO resurrect SSL session recycling; this means save the session on disconnect and look
62//for a reusable session on connect. Consider how HTTP persistent connections interact with that.
63
64//TODO in case we support SSL-lessness we need static KTcpSocket::sslAvailable() and check it
65//in most places we ATM check for d->isSSL.
66
67//TODO check if d->isBlocking is honored everywhere it makes sense
68
69//TODO fold KSSLSetting and KSSLCertificateHome into KSslSettings and use that everywhere.
70
71//TODO recognize partially encrypted websites as "somewhat safe"
72
73/* List of dialogs/messageboxes we need to use (current code location in parentheses)
74 - Can the "dontAskAgainName" thing be improved?
75
76 - "SSLCertDialog" [select client cert] (SlaveInterface)
77 - Enter password for client certificate (inline)
78 - Password for client cert was wrong. Please reenter. (inline)
79 - Setting client cert failed. [doesn't give reason] (inline)
80 - "SSLInfoDialog" [mostly server cert info] (SlaveInterface)
81 - You are about to enter secure mode. Security information/Display SSL information/Connect (inline)
82 - You are about to leave secure mode. Security information/Continue loading/Abort (inline)
83 - Hostname mismatch: Continue/Details/Cancel (inline)
84 - IP address mismatch: Continue/Details/Cancel (inline)
85 - Certificate failed authenticity check: Continue/Details/Cancel (inline)
86 - Would you like to accept this certificate forever: Yes/No/Current sessions only (inline)
87 */
88
89
91class TCPSlaveBase::TcpSlaveBasePrivate
92{
93public:
94 TcpSlaveBasePrivate(TCPSlaveBase* qq) : q(qq) {}
95
96 void setSslMetaData()
97 {
98 sslMetaData.insert("ssl_in_use", "TRUE");
99 KSslCipher cipher = socket.sessionCipher();
100 sslMetaData.insert("ssl_protocol_version", socket.negotiatedSslVersionName());
101 QString sslCipher = cipher.encryptionMethod() + '\n';
102 sslCipher += cipher.authenticationMethod() + '\n';
103 sslCipher += cipher.keyExchangeMethod() + '\n';
104 sslCipher += cipher.digestMethod();
105 sslMetaData.insert("ssl_cipher", sslCipher);
106 sslMetaData.insert("ssl_cipher_name", cipher.name());
107 sslMetaData.insert("ssl_cipher_used_bits", QString::number(cipher.usedBits()));
108 sslMetaData.insert("ssl_cipher_bits", QString::number(cipher.supportedBits()));
109 sslMetaData.insert("ssl_peer_ip", ip);
110
111 // try to fill in the blanks, i.e. missing certificates, and just assume that
112 // those belong to the peer (==website or similar) certificate.
113 for (int i = 0; i < sslErrors.count(); i++) {
114 if (sslErrors[i].certificate().isNull()) {
115 sslErrors[i] = KSslError(sslErrors[i].error(),
116 socket.peerCertificateChain()[0]);
117 }
118 }
119
120 QString errorStr;
121 // encode the two-dimensional numeric error list using '\n' and '\t' as outer and inner separators
122 Q_FOREACH (const QSslCertificate &cert, socket.peerCertificateChain()) {
123 Q_FOREACH (const KSslError &error, sslErrors) {
124 if (error.certificate() == cert) {
125 errorStr += QString::number(static_cast<int>(error.error())) + '\t';
126 }
127 }
128 if (errorStr.endsWith('\t')) {
129 errorStr.chop(1);
130 }
131 errorStr += '\n';
132 }
133 errorStr.chop(1);
134 sslMetaData.insert("ssl_cert_errors", errorStr);
135
136 QString peerCertChain;
137 Q_FOREACH (const QSslCertificate &cert, socket.peerCertificateChain()) {
138 peerCertChain.append(cert.toPem());
139 peerCertChain.append('\x01');
140 }
141 peerCertChain.chop(1);
142 sslMetaData.insert("ssl_peer_chain", peerCertChain);
143 sendSslMetaData();
144 }
145
146 void clearSslMetaData()
147 {
148 sslMetaData.clear();
149 sslMetaData.insert("ssl_in_use", "FALSE");
150 sendSslMetaData();
151 }
152
153 void sendSslMetaData()
154 {
155 MetaData::ConstIterator it = sslMetaData.constBegin();
156 for (; it != sslMetaData.constEnd(); ++it) {
157 q->setMetaData(it.key(), it.value());
158 }
159 }
160
161 SslResult startTLSInternal(KTcpSocket::SslVersion sslVersion,
162 const QSslConfiguration& configuration = QSslConfiguration(),
163 int waitForEncryptedTimeout = -1);
164
165 TCPSlaveBase* q;
166
167 bool isBlocking;
168
169 KTcpSocket socket;
170
171 QString host;
172 QString ip;
173 quint16 port;
174 QByteArray serviceName;
175
176 KSSLSettings sslSettings;
177 bool usingSSL;
178 bool autoSSL;
179 bool sslNoUi; // If true, we just drop the connection silently
180 // if SSL certificate check fails in some way.
181 QList<KSslError> sslErrors;
182
183 MetaData sslMetaData;
184};
185
186
187//### uh, is this a good idea??
188QIODevice *TCPSlaveBase::socket() const
189{
190 return &d->socket;
191}
192
193
194TCPSlaveBase::TCPSlaveBase(const QByteArray &protocol,
195 const QByteArray &poolSocket,
196 const QByteArray &appSocket,
197 bool autoSSL)
198 : SlaveBase(protocol, poolSocket, appSocket),
199 d(new TcpSlaveBasePrivate(this))
200{
201 d->isBlocking = true;
202 d->port = 0;
203 d->serviceName = protocol;
204 d->usingSSL = false;
205 d->autoSSL = autoSSL;
206 d->sslNoUi = false;
207 // Limit the read buffer size to 14 MB (14*1024*1024) (based on the upload limit
208 // in TransferJob::slotDataReq). See the docs for QAbstractSocket::setReadBufferSize
209 // and the BR# 187876 to understand why setting this limit is necessary.
210 d->socket.setReadBufferSize(14680064);
211}
212
213
214TCPSlaveBase::~TCPSlaveBase()
215{
216 delete d;
217}
218
219
220ssize_t TCPSlaveBase::write(const char *data, ssize_t len)
221{
222 ssize_t written = d->socket.write(data, len);
223 if (written == -1) {
224 kDebug(7027) << "d->socket.write() returned -1! Socket error is"
225 << d->socket.error() << ", Socket state is" << d->socket.state();
226 }
227
228 bool success = false;
229 if (d->isBlocking) {
230 // Drain the tx buffer
231 success = d->socket.waitForBytesWritten(-1);
232 } else {
233 // ### I don't know how to make sure that all data does get written at some point
234 // without doing it now. There is no event loop to do it behind the scenes.
235 // Polling in the dispatch() loop? Something timeout based?
236 success = d->socket.waitForBytesWritten(0);
237 }
238
239 d->socket.flush(); //this is supposed to get the data on the wire faster
240
241 if (d->socket.state() != KTcpSocket::ConnectedState || !success) {
242 kDebug(7027) << "Write failed, will return -1! Socket error is"
243 << d->socket.error() << ", Socket state is" << d->socket.state()
244 << "Return value of waitForBytesWritten() is" << success;
245 return -1;
246 }
247
248 return written;
249}
250
251
252ssize_t TCPSlaveBase::read(char* data, ssize_t len)
253{
254 if (d->usingSSL && (d->socket.encryptionMode() != KTcpSocket::SslClientMode)) {
255 d->clearSslMetaData();
256 kDebug(7029) << "lost SSL connection.";
257 return -1;
258 }
259
260 if (!d->socket.bytesAvailable()) {
261 const int timeout = d->isBlocking ? -1 : (readTimeout() * 1000);
262 d->socket.waitForReadyRead(timeout);
263 }
264#if 0
265 // Do not do this because its only benefit is to cause a nasty side effect
266 // upstream in Qt. See BR# 260769.
267 else if (d->socket.encryptionMode() != KTcpSocket::SslClientMode ||
268 QNetworkProxy::applicationProxy().type() == QNetworkProxy::NoProxy) {
269 // we only do this when it doesn't trigger Qt socket bugs. When it doesn't break anything
270 // it seems to help performance.
271 d->socket.waitForReadyRead(0);
272 }
273#endif
274 return d->socket.read(data, len);
275}
276
277
278ssize_t TCPSlaveBase::readLine(char *data, ssize_t len)
279{
280 if (d->usingSSL && (d->socket.encryptionMode() != KTcpSocket::SslClientMode)) {
281 d->clearSslMetaData();
282 kDebug(7029) << "lost SSL connection.";
283 return -1;
284 }
285
286 const int timeout = (d->isBlocking ? -1: (readTimeout() * 1000));
287 ssize_t readTotal = 0;
288 do {
289 if (!d->socket.bytesAvailable())
290 d->socket.waitForReadyRead(timeout);
291 ssize_t readStep = d->socket.readLine(&data[readTotal], len-readTotal);
292 if (readStep == -1 || (readStep == 0 && d->socket.state() != KTcpSocket::ConnectedState)) {
293 return -1;
294 }
295 readTotal += readStep;
296 } while (readTotal == 0 || data[readTotal-1] != '\n');
297
298 return readTotal;
299}
300
301
302bool TCPSlaveBase::connectToHost(const QString &/*protocol*/,
303 const QString &host,
304 quint16 port)
305{
306 QString errorString;
307 const int errCode = connectToHost(host, port, &errorString);
308 if (errCode == 0)
309 return true;
310
311 error(errCode, errorString);
312 return false;
313}
314
315int TCPSlaveBase::connectToHost(const QString& host, quint16 port, QString* errorString)
316{
317 d->clearSslMetaData(); //We have separate connection and SSL setup phases
318
319 if (errorString) {
320 errorString->clear(); // clear prior error messages.
321 }
322
323 d->socket.setVerificationPeerName(host); // Used for ssl certificate verification (SNI)
324
325 // - leaving SSL - warn before we even connect
326 //### see if it makes sense to move this into the HTTP ioslave which is the only
327 // user.
328 if (metaData("main_frame_request") == "TRUE" //### this looks *really* unreliable
329 && metaData("ssl_activate_warnings") == "TRUE"
330 && metaData("ssl_was_in_use") == "TRUE"
331 && !d->autoSSL) {
332 KSSLSettings kss;
333 if (kss.warnOnLeave()) {
334 int result = messageBox(i18n("You are about to leave secure "
335 "mode. Transmissions will no "
336 "longer be encrypted.\nThis "
337 "means that a third party could "
338 "observe your data in transit."),
339 WarningContinueCancel,
340 i18n("Security Information"),
341 i18n("C&ontinue Loading"), QString(),
342 "WarnOnLeaveSSLMode");
343
344 if (result == KMessageBox::Cancel) {
345 if (errorString)
346 *errorString = host;
347 return ERR_USER_CANCELED;
348 }
349 }
350 }
351
352 /*
353 By default the SSL handshake attempt uses these settings in the order shown:
354
355 1.) Protocol: KTcpSocket::SecureProtocols SSL compression: OFF (DEFAULT)
356 2.) Protocol: KTcpSocket::TlsV1 SSL compression: OFF
357 3.) Protocol: KTcpSocket::SslV3 SSL compression: OFF
358
359 If any combination other than the one marked DEFAULT is used to complete
360 the SSL handshake, then that combination will be cached using KIO's internal
361 meta-data mechanism in order to speed up future connections to the same host.
362 */
363
364 QSslConfiguration sslConfig = d->socket.sslConfiguration();
365
366#if QT_VERSION >= 0x040800
367 // NOTE: Due to 'CRIME' SSL attacks, compression is always disabled.
368 sslConfig.setSslOption(QSsl::SslOptionDisableCompression, true);
369#endif
370
371 const int lastSslVerson = config()->readEntry("LastUsedSslVersion", static_cast<int>(KTcpSocket::SecureProtocols));
372 KTcpSocket::SslVersion trySslVersion = static_cast<KTcpSocket::SslVersion>(lastSslVerson);
373 KTcpSocket::SslVersions alreadyTriedSslVersions = trySslVersion;
374
375 const int timeout = (connectTimeout() * 1000); // 20 sec timeout value
376 while (true) {
377 disconnectFromHost(); //Reset some state, even if we are already disconnected
378 d->host = host;
379
380 d->socket.connectToHost(host, port);
381 const bool connectOk = d->socket.waitForConnected(timeout > -1 ? timeout : -1);
382
383 kDebug(7027) << "Socket: state=" << d->socket.state()
384 << ", error=" << d->socket.error()
385 << ", connected?" << connectOk;
386
387 if (d->socket.state() != KTcpSocket::ConnectedState) {
388 if (errorString)
389 *errorString = host + QLatin1String(": ") + d->socket.errorString();
390 switch (d->socket.error()) {
391 case KTcpSocket::UnsupportedSocketOperationError:
392 return ERR_UNSUPPORTED_ACTION;
393 case KTcpSocket::RemoteHostClosedError:
394 return ERR_CONNECTION_BROKEN;
395 case KTcpSocket::SocketTimeoutError:
396 return ERR_SERVER_TIMEOUT;
397 case KTcpSocket::HostNotFoundError:
398 return ERR_UNKNOWN_HOST;
399 default:
400 return ERR_COULD_NOT_CONNECT;
401 }
402 }
403
404 //### check for proxyAuthenticationRequiredError
405
406 d->ip = d->socket.peerAddress().toString();
407 d->port = d->socket.peerPort();
408
409 if (d->autoSSL) {
410 SslResult res = d->startTLSInternal(trySslVersion, sslConfig, timeout);
411 if ((res & ResultFailed) && (res & ResultFailedEarly)) {
412 if (!(alreadyTriedSslVersions & KTcpSocket::SecureProtocols)) {
413 trySslVersion = KTcpSocket::SecureProtocols;
414 alreadyTriedSslVersions |= trySslVersion;
415 continue;
416 }
417
418 if (!(alreadyTriedSslVersions & KTcpSocket::TlsV1)) {
419 trySslVersion = KTcpSocket::TlsV1;
420 alreadyTriedSslVersions |= trySslVersion;
421 continue;
422 }
423
424 if (!(alreadyTriedSslVersions & KTcpSocket::SslV3)) {
425 trySslVersion = KTcpSocket::SslV3;
426 alreadyTriedSslVersions |= trySslVersion;
427 continue;
428 }
429 }
430
431 //### SSL 2.0 is (close to) dead and it's a good thing, too.
432 if (res & ResultFailed) {
433 if (errorString)
434 *errorString = i18nc("%1 is a host name", "%1: SSL negotiation failed", host);
435 return ERR_COULD_NOT_CONNECT;
436 }
437 }
438 // If the SSL handshake was done with anything protocol other than the default,
439 // save that information so that any subsequent requests do not have to do thesame thing.
440 if (trySslVersion != KTcpSocket::SecureProtocols && lastSslVerson == KTcpSocket::SecureProtocols) {
441 setMetaData(QLatin1String("{internal~currenthost}LastUsedSslVersion"),
442 QString::number(trySslVersion));
443 }
444 return 0;
445 }
446 Q_ASSERT(false);
447 // Code flow never gets here but let's make the compiler happy.
448 // More: the stack allocation of QSslSettings seems to be confusing the compiler;
449 // in fact, any non-POD allocation does.
450 // even a 'return 0;' directly after the allocation (so before the while(true))
451 // is ignored. definitely seems to be a compiler bug? - aseigo
452 return 0;
453}
454
455void TCPSlaveBase::disconnectFromHost()
456{
457 kDebug(7027);
458 d->host.clear();
459 d->ip.clear();
460 d->usingSSL = false;
461
462 if (d->socket.state() == KTcpSocket::UnconnectedState) {
463 // discard incoming data - the remote host might have disconnected us in the meantime
464 // but the visible effect of disconnectFromHost() should stay the same.
465 d->socket.close();
466 return;
467 }
468
469 //### maybe save a session for reuse on SSL shutdown if and when QSslSocket
470 // does that. QCA::TLS can do it apparently but that is not enough if
471 // we want to present that as KDE API. Not a big loss in any case.
472 d->socket.disconnectFromHost();
473 if (d->socket.state() != KTcpSocket::UnconnectedState)
474 d->socket.waitForDisconnected(-1); // wait for unsent data to be sent
475 d->socket.close(); //whatever that means on a socket
476}
477
478bool TCPSlaveBase::isAutoSsl() const
479{
480 return d->autoSSL;
481}
482
483bool TCPSlaveBase::isUsingSsl() const
484{
485 return d->usingSSL;
486}
487
488quint16 TCPSlaveBase::port() const
489{
490 return d->port;
491}
492
493bool TCPSlaveBase::atEnd() const
494{
495 return d->socket.atEnd();
496}
497
498bool TCPSlaveBase::startSsl()
499{
500 if (d->usingSSL)
501 return false;
502 return d->startTLSInternal(KTcpSocket::SecureProtocols) & ResultOk;
503}
504
505TCPSlaveBase::SslResult TCPSlaveBase::TcpSlaveBasePrivate::startTLSInternal (KTcpSocket::SslVersion version,
506 const QSslConfiguration& sslConfig,
507 int waitForEncryptedTimeout)
508{
509 q->selectClientCertificate();
510
511 //setMetaData("ssl_session_id", d->kssl->session()->toString());
512 //### we don't support session reuse for now...
513 usingSSL = true;
514#if QT_VERSION >= 0x040800
515 kDebug(7027) << "Trying SSL handshake with protocol:" << version
516 << ", SSL compression ON:" << sslConfig.testSslOption(QSsl::SslOptionDisableCompression);
517#endif
518 // Set the SSL version to use...
519 socket.setAdvertisedSslVersion(version);
520
521 // Set SSL configuration information
522 if (!sslConfig.isNull())
523 socket.setSslConfiguration(sslConfig);
524
525 /* Usually ignoreSslErrors() would be called in the slot invoked by the sslErrors()
526 signal but that would mess up the flow of control. We will check for errors
527 anyway to decide if we want to continue connecting. Otherwise ignoreSslErrors()
528 before connecting would be very insecure. */
529 socket.ignoreSslErrors();
530 socket.startClientEncryption();
531 const bool encryptionStarted = socket.waitForEncrypted(waitForEncryptedTimeout);
532
533 //Set metadata, among other things for the "SSL Details" dialog
534 KSslCipher cipher = socket.sessionCipher();
535
536 if (!encryptionStarted || socket.encryptionMode() != KTcpSocket::SslClientMode
537 || cipher.isNull() || cipher.usedBits() == 0 || socket.peerCertificateChain().isEmpty()) {
538 usingSSL = false;
539 clearSslMetaData();
540 kDebug(7029) << "Initial SSL handshake failed. encryptionStarted is"
541 << encryptionStarted << ", cipher.isNull() is" << cipher.isNull()
542 << ", cipher.usedBits() is" << cipher.usedBits()
543 << ", length of certificate chain is" << socket.peerCertificateChain().count()
544 << ", the socket says:" << socket.errorString()
545 << "and the list of SSL errors contains"
546 << socket.sslErrors().count() << "items.";
547 Q_FOREACH(const KSslError& sslError, socket.sslErrors()) {
548 kDebug(7029) << "SSL ERROR: (" << sslError.error() << ")" << sslError.errorString();
549 }
550 return ResultFailed | ResultFailedEarly;
551 }
552
553 kDebug(7029) << "Cipher info - "
554 << " advertised SSL protocol version" << socket.advertisedSslVersion()
555 << " negotiated SSL protocol version" << socket.negotiatedSslVersion()
556 << " authenticationMethod:" << cipher.authenticationMethod()
557 << " encryptionMethod:" << cipher.encryptionMethod()
558 << " keyExchangeMethod:" << cipher.keyExchangeMethod()
559 << " name:" << cipher.name()
560 << " supportedBits:" << cipher.supportedBits()
561 << " usedBits:" << cipher.usedBits();
562
563 sslErrors = socket.sslErrors();
564
565 // TODO: review / rewrite / remove the comment
566 // The app side needs the metadata now for the SSL error dialog (if any) but
567 // the same metadata will be needed later, too. When "later" arrives the slave
568 // may actually be connected to a different application that doesn't know
569 // the metadata the slave sent to the previous application.
570 // The quite important SSL indicator icon in Konqi's URL bar relies on metadata
571 // from here, for example. And Konqi will be the second application to connect
572 // to the slave.
573 // Therefore we choose to have our metadata and send it, too :)
574 setSslMetaData();
575 q->sendAndKeepMetaData();
576
577 SslResult rc = q->verifyServerCertificate();
578 if (rc & ResultFailed) {
579 usingSSL = false;
580 clearSslMetaData();
581 kDebug(7029) << "server certificate verification failed.";
582 socket.disconnectFromHost(); //Make the connection fail (cf. ignoreSslErrors())
583 return ResultFailed;
584 } else if (rc & ResultOverridden) {
585 kDebug(7029) << "server certificate verification failed but continuing at user's request.";
586 }
587
588 //"warn" when starting SSL/TLS
589 if (q->metaData("ssl_activate_warnings") == "TRUE"
590 && q->metaData("ssl_was_in_use") == "FALSE"
591 && sslSettings.warnOnEnter()) {
592
593 int msgResult = q->messageBox(i18n("You are about to enter secure mode. "
594 "All transmissions will be encrypted "
595 "unless otherwise noted.\nThis means "
596 "that no third party will be able to "
597 "easily observe your data in transit."),
598 WarningYesNo,
599 i18n("Security Information"),
600 i18n("Display SSL &Information"),
601 i18n("C&onnect"),
602 "WarnOnEnterSSLMode");
603 if (msgResult == KMessageBox::Yes) {
604 q->messageBox(SSLMessageBox /*==the SSL info dialog*/, host);
605 }
606 }
607
608 return rc;
609}
610
611void TCPSlaveBase::selectClientCertificate()
612{
613#if 0 //hehe
614 QString certname; // the cert to use this session
615 bool send = false, prompt = false, save = false, forcePrompt = false;
616 KSSLCertificateHome::KSSLAuthAction aa;
617
618 setMetaData("ssl_using_client_cert", "FALSE"); // we change this if needed
619
620 if (metaData("ssl_no_client_cert") == "TRUE") return;
621 forcePrompt = (metaData("ssl_force_cert_prompt") == "TRUE");
622
623 // Delete the old cert since we're certainly done with it now
624 if (d->pkcs) {
625 delete d->pkcs;
626 d->pkcs = NULL;
627 }
628
629 if (!d->kssl) return;
630
631 // Look for a general certificate
632 if (!forcePrompt) {
633 certname = KSSLCertificateHome::getDefaultCertificateName(&aa);
634 switch (aa) {
635 case KSSLCertificateHome::AuthSend:
636 send = true; prompt = false;
637 break;
638 case KSSLCertificateHome::AuthDont:
639 send = false; prompt = false;
640 certname.clear();
641 break;
642 case KSSLCertificateHome::AuthPrompt:
643 send = false; prompt = true;
644 break;
645 default:
646 break;
647 }
648 }
649
650 // Look for a certificate on a per-host basis as an override
651 QString tmpcn = KSSLCertificateHome::getDefaultCertificateName(d->host, &aa);
652 if (aa != KSSLCertificateHome::AuthNone) { // we must override
653 switch (aa) {
654 case KSSLCertificateHome::AuthSend:
655 send = true;
656 prompt = false;
657 certname = tmpcn;
658 break;
659 case KSSLCertificateHome::AuthDont:
660 send = false;
661 prompt = false;
662 certname.clear();
663 break;
664 case KSSLCertificateHome::AuthPrompt:
665 send = false;
666 prompt = true;
667 certname = tmpcn;
668 break;
669 default:
670 break;
671 }
672 }
673
674 // Finally, we allow the application to override anything.
675 if (hasMetaData("ssl_demand_certificate")) {
676 certname = metaData("ssl_demand_certificate");
677 if (!certname.isEmpty()) {
678 forcePrompt = false;
679 prompt = false;
680 send = true;
681 }
682 }
683
684 if (certname.isEmpty() && !prompt && !forcePrompt) return;
685
686 // Ok, we're supposed to prompt the user....
687 if (prompt || forcePrompt) {
688 QStringList certs = KSSLCertificateHome::getCertificateList();
689
690 QStringList::const_iterator it = certs.begin();
691 while (it != certs.end()) {
692 KSSLPKCS12 *pkcs = KSSLCertificateHome::getCertificateByName(*it);
693 if (pkcs && (!pkcs->getCertificate() ||
694 !pkcs->getCertificate()->x509V3Extensions().certTypeSSLClient())) {
695 it = certs.erase(it);
696 } else {
697 ++it;
698 }
699 delete pkcs;
700 }
701
702 if (certs.isEmpty()) return; // we had nothing else, and prompt failed
703
704 if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kio.uiserver")) {
705 KToolInvocation::startServiceByDesktopPath("kuiserver.desktop",
706 QStringList());
707 }
708
709 QDBusInterface uis("org.kde.kio.uiserver", "/UIServer", "org.kde.KIO.UIServer");
710
711 QDBusMessage retVal = uis.call("showSSLCertDialog", d->host, certs, metaData("window-id").toLongLong());
712 if (retVal.type() == QDBusMessage::ReplyMessage) {
713 if (retVal.arguments().at(0).toBool()) {
714 send = retVal.arguments().at(1).toBool();
715 save = retVal.arguments().at(2).toBool();
716 certname = retVal.arguments().at(3).toString();
717 }
718 }
719 }
720
721 // The user may have said to not send the certificate,
722 // but to save the choice
723 if (!send) {
724 if (save) {
725 KSSLCertificateHome::setDefaultCertificate(certname, d->host,
726 false, false);
727 }
728 return;
729 }
730
731 // We're almost committed. If we can read the cert, we'll send it now.
732 KSSLPKCS12 *pkcs = KSSLCertificateHome::getCertificateByName(certname);
733 if (!pkcs && KSSLCertificateHome::hasCertificateByName(certname)) { // We need the password
734 KIO::AuthInfo ai;
735 bool first = true;
736 do {
737 ai.prompt = i18n("Enter the certificate password:");
738 ai.caption = i18n("SSL Certificate Password");
739 ai.url.setProtocol("kssl");
740 ai.url.setHost(certname);
741 ai.username = certname;
742 ai.keepPassword = true;
743
744 bool showprompt;
745 if (first)
746 showprompt = !checkCachedAuthentication(ai);
747 else
748 showprompt = true;
749 if (showprompt) {
750 if (!openPasswordDialog(ai, first ? QString() :
751 i18n("Unable to open the certificate. Try a new password?")))
752 break;
753 }
754
755 first = false;
756 pkcs = KSSLCertificateHome::getCertificateByName(certname, ai.password);
757 } while (!pkcs);
758
759 }
760
761 // If we could open the certificate, let's send it
762 if (pkcs) {
763 if (!d->kssl->setClientCertificate(pkcs)) {
764 messageBox(Information, i18n("The procedure to set the "
765 "client certificate for the session "
766 "failed."), i18n("SSL"));
767 delete pkcs; // we don't need this anymore
768 pkcs = 0L;
769 } else {
770 kDebug(7029) << "Client SSL certificate is being used.";
771 setMetaData("ssl_using_client_cert", "TRUE");
772 if (save) {
773 KSSLCertificateHome::setDefaultCertificate(certname, d->host,
774 true, false);
775 }
776 }
777 d->pkcs = pkcs;
778 }
779#endif
780}
781
782TCPSlaveBase::SslResult TCPSlaveBase::verifyServerCertificate()
783{
784 d->sslNoUi = hasMetaData("ssl_no_ui") && (metaData("ssl_no_ui") != "FALSE");
785
786 if (d->sslErrors.isEmpty()) {
787 return ResultOk;
788 } else if (d->sslNoUi) {
789 return ResultFailed;
790 }
791
792 QList<KSslError> fatalErrors = KSslCertificateManager::nonIgnorableErrors(d->sslErrors);
793 if (!fatalErrors.isEmpty()) {
794 //TODO message "sorry, fatal error, you can't override it"
795 return ResultFailed;
796 }
797
798 KSslCertificateManager *const cm = KSslCertificateManager::self();
799 KSslCertificateRule rule = cm->rule(d->socket.peerCertificateChain().first(), d->host);
800
801 // remove previously seen and acknowledged errors
802 QList<KSslError> remainingErrors = rule.filterErrors(d->sslErrors);
803 if (remainingErrors.isEmpty()) {
804 kDebug(7029) << "Error list empty after removing errors to be ignored. Continuing.";
805 return ResultOk | ResultOverridden;
806 }
807
808 //### We don't ask to permanently reject the certificate
809
810 QString message = i18n("The server failed the authenticity check (%1).\n\n", d->host);
811 Q_FOREACH (const KSslError &err, d->sslErrors) {
812 message.append(err.errorString());
813 message.append('\n');
814 }
815 message = message.trimmed();
816
817 int msgResult;
818 QDateTime ruleExpiry = QDateTime::currentDateTime();
819 do {
820 msgResult = messageBox(WarningYesNoCancel, message,
821 i18n("Server Authentication"),
822 i18n("&Details"), i18n("Co&ntinue"));
823 switch (msgResult) {
824 case KMessageBox::Yes:
825 //Details was chosen- show the certificate and error details
826 messageBox(SSLMessageBox /*the SSL info dialog*/, d->host);
827 break;
828 case KMessageBox::No: {
829 //fall through on KMessageBox::No
830 const int result = messageBox(WarningYesNoCancel,
831 i18n("Would you like to accept this "
832 "certificate forever without "
833 "being prompted?"),
834 i18n("Server Authentication"),
835 i18n("&Forever"),
836 i18n("&Current Session only"));
837 if (result == KMessageBox::Yes) {
838 //accept forever ("for a very long time")
839 ruleExpiry = ruleExpiry.addYears(1000);
840 } else if (result == KMessageBox::No) {
841 //accept "for a short time", half an hour.
842 ruleExpiry = ruleExpiry.addSecs(30*60);
843 } else {
844 msgResult = KMessageBox::Yes;
845 }
846 break;
847 }
848 case KMessageBox::Cancel:
849 return ResultFailed;
850 default:
851 kWarning() << "Unexpected MessageBox response received:" << msgResult;
852 return ResultFailed;
853 }
854 } while (msgResult == KMessageBox::Yes);
855
856 //TODO special cases for wildcard domain name in the certificate!
857 //rule = KSslCertificateRule(d->socket.peerCertificateChain().first(), whatever);
858
859 rule.setExpiryDateTime(ruleExpiry);
860 rule.setIgnoredErrors(d->sslErrors);
861
862 //Save the user's choice to ignore the SSL errors.
863 cm->setRule(rule);
864
865 return ResultOk | ResultOverridden;
866#if 0 //### need to to do something like the old code about the main and subframe stuff
867 kDebug(7029) << "SSL HTTP frame the parent? " << metaData("main_frame_request");
868 if (!hasMetaData("main_frame_request") || metaData("main_frame_request") == "TRUE") {
869 // Since we're the parent, we need to teach the child.
870 setMetaData("ssl_parent_ip", d->ip);
871 setMetaData("ssl_parent_cert", pc.toString());
872 // - Read from cache and see if there is a policy for this
873 KSSLCertificateCache::KSSLCertificatePolicy cp =
874 d->certCache->getPolicyByCertificate(pc);
875
876 // - validation code
877 if (ksv != KSSLCertificate::Ok) {
878 if (d->sslNoUi) {
879 return -1;
880 }
881
882 if (cp == KSSLCertificateCache::Unknown ||
883 cp == KSSLCertificateCache::Ambiguous) {
884 cp = KSSLCertificateCache::Prompt;
885 } else {
886 // A policy was already set so let's honor that.
887 permacache = d->certCache->isPermanent(pc);
888 }
889
890 if (!_IPmatchesCN && cp == KSSLCertificateCache::Accept) {
891 cp = KSSLCertificateCache::Prompt;
892// ksv = KSSLCertificate::Ok;
893 }
894
896
897 // - cache the results
898 d->certCache->addCertificate(pc, cp, permacache);
899 if (doAddHost) d->certCache->addHost(pc, d->host);
900 } else { // Child frame
901 // - Read from cache and see if there is a policy for this
902 KSSLCertificateCache::KSSLCertificatePolicy cp =
903 d->certCache->getPolicyByCertificate(pc);
904 isChild = true;
905
906 // Check the cert and IP to make sure they're the same
907 // as the parent frame
908 bool certAndIPTheSame = (d->ip == metaData("ssl_parent_ip") &&
909 pc.toString() == metaData("ssl_parent_cert"));
910
911 if (ksv == KSSLCertificate::Ok) {
912 if (certAndIPTheSame) { // success
913 rc = 1;
914 setMetaData("ssl_action", "accept");
915 } else {
916 /*
917 if (d->sslNoUi) {
918 return -1;
919 }
920 result = messageBox(WarningYesNo,
921 i18n("The certificate is valid but does not appear to have been assigned to this server. Do you wish to continue loading?"),
922 i18n("Server Authentication"));
923 if (result == KMessageBox::Yes) { // success
924 rc = 1;
925 setMetaData("ssl_action", "accept");
926 } else { // fail
927 rc = -1;
928 setMetaData("ssl_action", "reject");
929 }
930 */
931 setMetaData("ssl_action", "accept");
932 rc = 1; // Let's accept this now. It's bad, but at least the user
933 // will see potential attacks in KDE3 with the pseudo-lock
934 // icon on the toolbar, and can investigate with the RMB
935 }
936 } else {
937 if (d->sslNoUi) {
938 return -1;
939 }
940
941 if (cp == KSSLCertificateCache::Accept) {
942 if (certAndIPTheSame) { // success
943 rc = 1;
944 setMetaData("ssl_action", "accept");
945 } else { // fail
946 result = messageBox(WarningYesNo,
947 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?"),
948 i18n("Server Authentication"));
949 if (result == KMessageBox::Yes) {
950 rc = 1;
951 setMetaData("ssl_action", "accept");
952 d->certCache->addHost(pc, d->host);
953 } else {
954 rc = -1;
955 setMetaData("ssl_action", "reject");
956 }
957 }
958 } else if (cp == KSSLCertificateCache::Reject) { // fail
959 messageBox(Information, i18n("SSL certificate is being rejected as requested. You can disable this in the KDE System Settings."),
960 i18n("Server Authentication"));
961 rc = -1;
962 setMetaData("ssl_action", "reject");
963 } else {
964
966
967 return rc;
968#endif //#if 0
969 return ResultOk | ResultOverridden;
970}
971
972
973bool TCPSlaveBase::isConnected() const
974{
975 //QSslSocket::isValid() and therefore KTcpSocket::isValid() are shady...
976 return d->socket.state() == KTcpSocket::ConnectedState;
977}
978
979
980bool TCPSlaveBase::waitForResponse(int t)
981{
982 if (d->socket.bytesAvailable()) {
983 return true;
984 }
985 return d->socket.waitForReadyRead(t * 1000);
986}
987
988void TCPSlaveBase::setBlocking(bool b)
989{
990 if (!b) {
991 kWarning(7029) << "Caller requested non-blocking mode, but that doesn't work";
992 return;
993 }
994 d->isBlocking = b;
995}
996
997void TCPSlaveBase::virtual_hook(int id, void* data)
998{
999 if (id == SlaveBase::AppConnectionMade) {
1000 d->sendSslMetaData();
1001 } else {
1002 SlaveBase::virtual_hook(id, data);
1003 }
1004}
KConfigGroup::readEntry
QString readEntry(const char *key, const char *aDefault=0) const
KIO::AuthInfo
This class is intended to make it easier to prompt for, cache and retrieve authorization information.
Definition: authinfo.h:58
KIO::AuthInfo::keepPassword
bool keepPassword
Flag to indicate the persistence of the given password.
Definition: authinfo.h:232
KIO::AuthInfo::caption
QString caption
The text to displayed in the title bar of the password prompting dialog.
Definition: authinfo.h:142
KIO::AuthInfo::url
KUrl url
The URL for which authentication is to be stored.
Definition: authinfo.h:110
KIO::AuthInfo::username
QString username
This is required for caching.
Definition: authinfo.h:115
KIO::AuthInfo::password
QString password
This is required for caching.
Definition: authinfo.h:120
KIO::AuthInfo::prompt
QString prompt
Information to be displayed when prompting the user for authentication information.
Definition: authinfo.h:131
KIO::MetaData
MetaData is a simple map of key/value strings.
Definition: global.h:397
KIO::SlaveBase
There are two classes that specifies the protocol between application (job) and kioslave.
Definition: slavebase.h:51
KIO::SlaveBase::AppConnectionMade
@ AppConnectionMade
Definition: slavebase.h:897
KIO::SlaveBase::metaData
QString metaData(const QString &key) const
Queries for config/meta-data send by the application to the slave.
Definition: slavebase.cpp:346
KIO::SlaveBase::connectTimeout
int connectTimeout()
Definition: slavebase.cpp:1227
KIO::SlaveBase::written
void written(KIO::filesize_t _bytes)
Definition: slavebase.cpp:541
KIO::SlaveBase::error
void error(int _errid, const QString &_text)
Call to signal an error.
Definition: slavebase.cpp:419
KIO::SlaveBase::messageBox
int messageBox(MessageBoxType type, const QString &text, const QString &caption=QString(), const QString &buttonYes=i18n("&Yes"), const QString &buttonNo=i18n("&No"))
Call this to show a message box from the slave.
Definition: slavebase.cpp:851
KIO::SlaveBase::hasMetaData
bool hasMetaData(const QString &key) const
Queries for the existence of a certain config/meta-data entry send by the application to the slave.
Definition: slavebase.cpp:360
KIO::SlaveBase::openPasswordDialog
bool openPasswordDialog(KIO::AuthInfo &info, const QString &errorMsg=QString())
Prompt the user for Authorization info (login & password).
Definition: slavebase.cpp:815
KIO::SlaveBase::WarningYesNoCancel
@ WarningYesNoCancel
Definition: slavebase.h:248
KIO::SlaveBase::Information
@ Information
Definition: slavebase.h:248
KIO::SlaveBase::SSLMessageBox
@ SSLMessageBox
Definition: slavebase.h:248
KIO::SlaveBase::WarningContinueCancel
@ WarningContinueCancel
Definition: slavebase.h:248
KIO::SlaveBase::WarningYesNo
@ WarningYesNo
Definition: slavebase.h:248
KIO::SlaveBase::virtual_hook
virtual void virtual_hook(int id, void *data)
Definition: slavebase.cpp:1288
KIO::SlaveBase::data
void data(const QByteArray &data)
Sends data in the slave to the job (i.e.
Definition: slavebase.cpp:398
KIO::SlaveBase::readTimeout
int readTimeout()
Definition: slavebase.cpp:1259
KIO::SlaveBase::checkCachedAuthentication
bool checkCachedAuthentication(AuthInfo &info)
Checks for cached authentication based on parameters given by info.
Definition: slavebase.cpp:1175
KIO::SlaveBase::setMetaData
void setMetaData(const QString &key, const QString &value)
Sets meta-data to be send to the application before the first data() or finished() signal.
Definition: slavebase.cpp:341
KIO::SlaveBase::config
KConfigGroup * config()
Returns a configuration object to query config/meta-data information from.
Definition: slavebase.cpp:369
KIO::TCPSlaveBase
There are two classes that specifies the protocol between application (job) and kioslave.
Definition: tcpslavebase.h:47
KIO::TCPSlaveBase::write
ssize_t write(const char *data, ssize_t len)
Definition: tcpslavebase.cpp:220
KIO::TCPSlaveBase::~TCPSlaveBase
virtual ~TCPSlaveBase()
Definition: tcpslavebase.cpp:214
KIO::TCPSlaveBase::startSsl
bool startSsl()
Start using SSL on the connection.
Definition: tcpslavebase.cpp:498
KIO::TCPSlaveBase::setBlocking
void setBlocking(bool b)
Sets the mode of the connection to blocking or non-blocking.
Definition: tcpslavebase.cpp:988
KIO::TCPSlaveBase::connectToHost
bool connectToHost(const QString &protocol, const QString &host, quint16 port)
Performs the initial TCP connection stuff and/or SSL handshaking as necessary.
Definition: tcpslavebase.cpp:302
KIO::TCPSlaveBase::TCPSlaveBase
TCPSlaveBase(const QByteArray &protocol, const QByteArray &poolSocket, const QByteArray &appSocket, bool autoSsl=false)
Constructor.
Definition: tcpslavebase.cpp:194
KIO::TCPSlaveBase::ResultFailed
@ ResultFailed
Definition: tcpslavebase.h:66
KIO::TCPSlaveBase::ResultOk
@ ResultOk
Definition: tcpslavebase.h:64
KIO::TCPSlaveBase::ResultFailedEarly
@ ResultFailedEarly
Definition: tcpslavebase.h:67
KIO::TCPSlaveBase::ResultOverridden
@ ResultOverridden
Definition: tcpslavebase.h:65
KIO::TCPSlaveBase::disconnectFromHost
void disconnectFromHost()
Close the connection and forget non-permanent data like the peer host.
Definition: tcpslavebase.cpp:455
KIO::TCPSlaveBase::virtual_hook
virtual void virtual_hook(int id, void *data)
Definition: tcpslavebase.cpp:997
KIO::TCPSlaveBase::port
quint16 port() const
the current port for this service
Definition: tcpslavebase.cpp:488
KIO::TCPSlaveBase::isAutoSsl
bool isAutoSsl() const
Will start SSL after connecting?
Definition: tcpslavebase.cpp:478
KIO::TCPSlaveBase::socket
QIODevice * socket() const
Return the socket object, if the class ever needs to do anything to it.
Definition: tcpslavebase.cpp:188
KIO::TCPSlaveBase::waitForResponse
bool waitForResponse(int t)
Wait for incoming data on the socket for the period specified by t.
Definition: tcpslavebase.cpp:980
KIO::TCPSlaveBase::readLine
ssize_t readLine(char *data, ssize_t len)
Same as read() except it reads data one line at a time.
Definition: tcpslavebase.cpp:278
KIO::TCPSlaveBase::atEnd
bool atEnd() const
Returns true when end of data is reached.
Definition: tcpslavebase.cpp:493
KIO::TCPSlaveBase::isUsingSsl
bool isUsingSsl() const
Is the current connection using SSL?
Definition: tcpslavebase.cpp:483
KIO::TCPSlaveBase::read
ssize_t read(char *data, ssize_t len)
Definition: tcpslavebase.cpp:252
KIO::TCPSlaveBase::isConnected
bool isConnected() const
Determines whether or not we are still connected to the remote machine.
Definition: tcpslavebase.cpp:973
KMessageBox::Yes
Yes
KMessageBox::No
No
KMessageBox::Cancel
Cancel
KSSLCertificateHome::getCertificateByName
static KSSLPKCS12 * getCertificateByName(const QString &name, const QString &password)
Definition: ksslcertificatehome.cpp:105
KSSLCertificateHome::getCertificateList
static QStringList getCertificateList()
Definition: ksslcertificatehome.cpp:28
KSSLCertificateHome::setDefaultCertificate
static void setDefaultCertificate(const QString &name, bool send=true, bool prompt=false)
Definition: ksslcertificatehome.cpp:208
KSSLCertificateHome::hasCertificateByName
static bool hasCertificateByName(const QString &name)
Definition: ksslcertificatehome.cpp:127
KSSLCertificateHome::getDefaultCertificateName
static QString getDefaultCertificateName(const QString &host, KSSLAuthAction *aa=NULL)
Definition: ksslcertificatehome.cpp:140
KSSLCertificateHome::KSSLAuthAction
KSSLAuthAction
Definition: ksslcertificatehome.h:36
KSSLCertificateHome::AuthPrompt
@ AuthPrompt
Definition: ksslcertificatehome.h:36
KSSLCertificateHome::AuthNone
@ AuthNone
Definition: ksslcertificatehome.h:36
KSSLCertificateHome::AuthSend
@ AuthSend
Definition: ksslcertificatehome.h:36
KSSLCertificateHome::AuthDont
@ AuthDont
Definition: ksslcertificatehome.h:36
KSSLCertificate::x509V3Extensions
KSSLX509V3 & x509V3Extensions()
Access the X.509v3 parameters.
Definition: ksslcertificate.cpp:1288
KSSLCertificate::Ok
@ Ok
Definition: ksslcertificate.h:119
KSSLPKCS12
KDE PKCS#12 Certificate.
Definition: ksslpkcs12.h:63
KSSLPKCS12::getCertificate
KSSLCertificate * getCertificate()
Get the X.509 certificate.
Definition: ksslpkcs12.cpp:190
KSSLSettings
KDE SSL Settings.
Definition: ksslsettings.h:41
KSSLSettings::warnOnLeave
bool warnOnLeave() const
Does the user want to be warned on leaving SSL mode.
Definition: ksslsettings.cpp:214
KSSLX509V3::certTypeSSLClient
bool certTypeSSLClient() const
Determine if this certificate can be used by an SSL client.
Definition: ksslx509v3.cpp:83
KSslCertificateManager
KSslCertificateManager::nonIgnorableErrors
static QList< KSslError > nonIgnorableErrors(const QList< KSslError > &)
KSslCertificateManager::self
static KSslCertificateManager * self()
KSslCertificateManager::rule
KSslCertificateRule rule(const QSslCertificate &cert, const QString &hostName) const
KSslCertificateManager::setRule
void setRule(const KSslCertificateRule &rule)
KSslCertificateRule
KSslCertificateRule::setExpiryDateTime
void setExpiryDateTime(const QDateTime &dateTime)
KSslCertificateRule::setIgnoredErrors
void setIgnoredErrors(const QList< KSslError > &errors)
KSslCertificateRule::filterErrors
QList< KSslError > filterErrors(const QList< KSslError > &errors) const
KSslCipher
KSslCipher::usedBits
int usedBits() const
KSslCipher::encryptionMethod
QString encryptionMethod() const
KSslCipher::name
QString name() const
KSslCipher::isNull
bool isNull() const
KSslCipher::keyExchangeMethod
QString keyExchangeMethod() const
KSslCipher::authenticationMethod
QString authenticationMethod() const
KSslCipher::digestMethod
QString digestMethod() const
KSslCipher::supportedBits
int supportedBits() const
KSslError
KSslError::error
Error error() const
KSslError::errorString
QString errorString() const
KTcpSocket
KTcpSocket::SslClientMode
SslClientMode
KTcpSocket::SslVersion
SslVersion
KTcpSocket::SslV3
SslV3
KTcpSocket::TlsV1
TlsV1
KTcpSocket::SecureProtocols
SecureProtocols
KTcpSocket::UnconnectedState
UnconnectedState
KTcpSocket::ConnectedState
ConnectedState
KTcpSocket::SocketTimeoutError
SocketTimeoutError
KTcpSocket::UnsupportedSocketOperationError
UnsupportedSocketOperationError
KTcpSocket::RemoteHostClosedError
RemoteHostClosedError
KTcpSocket::HostNotFoundError
HostNotFoundError
KToolInvocation::startServiceByDesktopPath
static int startServiceByDesktopPath(const QString &_name, const QString &URL, QString *error=0, QString *serviceName=0, int *pid=0, const QByteArray &startup_id=QByteArray(), bool noWait=false)
KUrl::setProtocol
void setProtocol(const QString &proto)
QIODevice
QList
QMap
kDebug
#define kDebug
kWarning
#define kWarning
kconfiggroup.h
kdebug.h
timeout
int timeout
klocale.h
i18n
QString i18n(const char *text)
i18nc
QString i18nc(const char *ctxt, const char *text)
kmessagebox.h
ksslcertificatemanager.h
ksslsettings.h
ktcpsocket.h
ktoolinvocation.h
KIO
A namespace for KIO globals.
Definition: kbookmarkmenu.h:55
KIO::ERR_CONNECTION_BROKEN
@ ERR_CONNECTION_BROKEN
Definition: global.h:218
KIO::ERR_COULD_NOT_CONNECT
@ ERR_COULD_NOT_CONNECT
Definition: global.h:217
KIO::ERR_UNSUPPORTED_ACTION
@ ERR_UNSUPPORTED_ACTION
Definition: global.h:202
KIO::ERR_USER_CANCELED
@ ERR_USER_CANCELED
Definition: global.h:214
KIO::ERR_UNKNOWN_HOST
@ ERR_UNKNOWN_HOST
Definition: global.h:208
KIO::ERR_SERVER_TIMEOUT
@ ERR_SERVER_TIMEOUT
Definition: global.h:244
message
void message(KMessage::MessageType messageType, const QString &text, const QString &caption=QString())
save
KAction * save(const QObject *recvr, const char *slot, QObject *parent)
StringStringMap
QMap< QString, QString > StringStringMap
Definition: tcpslavebase.cpp:51
tcpslavebase.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KIO

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

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal