KIO

ktcpsocket.cpp
1 /*
2  This file is part of the KDE libraries
3  SPDX-FileCopyrightText: 2007, 2008 Andreas Hartmetz <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #include "ktcpsocket.h"
9 #include "ksslerror_p.h"
10 #include "kiocoredebug.h"
11 
12 #include <ksslcertificatemanager.h>
13 #include <KLocalizedString>
14 
15 #include <QUrl>
16 #include <QSslKey>
17 #include <QSslCipher>
18 #include <QHostAddress>
19 #include <QNetworkProxy>
20 #include <QAuthenticator>
21 
22 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 65)
23 
24 static KTcpSocket::SslVersion kSslVersionFromQ(QSsl::SslProtocol protocol)
25 {
26  switch (protocol) {
27  case QSsl::SslV2:
28  return KTcpSocket::SslV2;
29  case QSsl::SslV3:
30  return KTcpSocket::SslV3;
31  case QSsl::TlsV1_0:
32  return KTcpSocket::TlsV1;
33  case QSsl::TlsV1_1:
34  return KTcpSocket::TlsV1_1;
35  case QSsl::TlsV1_2:
36  return KTcpSocket::TlsV1_2;
37  case QSsl::TlsV1_3:
38  return KTcpSocket::TlsV1_3;
39  case QSsl::AnyProtocol:
40  return KTcpSocket::AnySslVersion;
41  case QSsl::TlsV1SslV3:
42  return KTcpSocket::TlsV1SslV3;
44  return KTcpSocket::SecureProtocols;
45  default:
46  return KTcpSocket::UnknownSslVersion;
47  }
48 }
49 
50 static QSsl::SslProtocol qSslProtocolFromK(KTcpSocket::SslVersion sslVersion)
51 {
52  //### this lowlevel bit-banging is a little dangerous and a likely source of bugs
53  if (sslVersion == KTcpSocket::AnySslVersion) {
54  return QSsl::AnyProtocol;
55  }
56  //does it contain any valid protocol?
57  KTcpSocket::SslVersions validVersions(KTcpSocket::SslV2 | KTcpSocket::SslV3 | KTcpSocket::TlsV1);
58  validVersions |= KTcpSocket::TlsV1_1;
59  validVersions |= KTcpSocket::TlsV1_2;
60  validVersions |= KTcpSocket::TlsV1_3;
61  validVersions |= KTcpSocket::TlsV1SslV3;
62  validVersions |= KTcpSocket::SecureProtocols;
63 
64  if (!(sslVersion & validVersions)) {
65  return QSsl::UnknownProtocol;
66  }
67 
68  switch (sslVersion) {
69  case KTcpSocket::SslV2:
70  return QSsl::SslV2;
71  case KTcpSocket::SslV3:
72  return QSsl::SslV3;
73  case KTcpSocket::TlsV1_0:
74  return QSsl::TlsV1_0;
75  case KTcpSocket::TlsV1_1:
76  return QSsl::TlsV1_1;
77  case KTcpSocket::TlsV1_2:
78  return QSsl::TlsV1_2;
79  case KTcpSocket::TlsV1_3:
80  return QSsl::TlsV1_3;
81  case KTcpSocket::TlsV1SslV3:
82  return QSsl::TlsV1SslV3;
83  case KTcpSocket::SecureProtocols:
84  return QSsl::SecureProtocols;
85 
86  default:
87  //QSslSocket doesn't really take arbitrary combinations. It's one or all.
88  return QSsl::AnyProtocol;
89  }
90 }
91 
92 static QString protocolString(QSsl::SslProtocol protocol)
93 {
94  switch (protocol) {
95  case QSsl::SslV2:
96  return QStringLiteral("SSLv2");
97  case QSsl::SslV3:
98  return QStringLiteral("SSLv3");
99  case QSsl::TlsV1_0:
100  return QStringLiteral("TLSv1.0");
101  case QSsl::TlsV1_1:
102  return QStringLiteral("TLSv1.1");
103  case QSsl::TlsV1_2:
104  return QStringLiteral("TLSv1.2");
105  case QSsl::TlsV1_3:
106  return QStringLiteral("TLSv1.3");
107  default:
108  return QStringLiteral("Unknown");;
109  }
110 }
111 
112 //cipher class converter KSslCipher -> QSslCipher
113 class CipherCc
114 {
115 public:
116  CipherCc()
117  {
119  for (const QSslCipher &c : list) {
120  allCiphers.insert(c.name(), c);
121  }
122  }
123 
124  QSslCipher converted(const KSslCipher &ksc)
125  {
126  return allCiphers.value(ksc.name());
127  }
128 
129 private:
130  QHash<QString, QSslCipher> allCiphers;
131 };
132 
133 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 65)
134 KSslError::Error KSslErrorPrivate::errorFromQSslError(QSslError::SslError e)
135 {
136  switch (e) {
137  case QSslError::NoError:
138  return KSslError::NoError;
141  return KSslError::InvalidCertificateAuthorityCertificate;
146  return KSslError::ExpiredCertificate;
150  return KSslError::InvalidCertificate;
153  return KSslError::SelfSignedCertificate;
155  return KSslError::RevokedCertificate;
157  return KSslError::InvalidCertificatePurpose;
159  return KSslError::UntrustedCertificate;
161  return KSslError::RejectedCertificate;
163  return KSslError::NoPeerCertificate;
165  return KSslError::HostNameMismatch;
170  return KSslError::CertificateSignatureFailed;
172  return KSslError::PathLengthExceeded;
175  default:
176  return KSslError::UnknownError;
177  }
178 }
179 
180 QSslError::SslError KSslErrorPrivate::errorFromKSslError(KSslError::Error e)
181 {
182  switch (e) {
183  case KSslError::NoError:
184  return QSslError::NoError;
185  case KSslError::InvalidCertificateAuthorityCertificate:
187  case KSslError::InvalidCertificate:
189  case KSslError::CertificateSignatureFailed:
191  case KSslError::SelfSignedCertificate:
193  case KSslError::ExpiredCertificate:
195  case KSslError::RevokedCertificate:
197  case KSslError::InvalidCertificatePurpose:
199  case KSslError::RejectedCertificate:
201  case KSslError::UntrustedCertificate:
203  case KSslError::NoPeerCertificate:
205  case KSslError::HostNameMismatch:
207  case KSslError::PathLengthExceeded:
209  case KSslError::UnknownError:
210  default:
212  }
213 }
214 
215 KSslError::KSslError(Error errorCode, const QSslCertificate &certificate)
216  : d(new KSslErrorPrivate())
217 {
218  d->error = QSslError(d->errorFromKSslError(errorCode), certificate);
219 }
220 
221 KSslError::KSslError(const QSslError &other)
222  : d(new KSslErrorPrivate())
223 {
224  d->error = other;
225 }
226 
227 KSslError::KSslError(const KSslError &other)
228  : d(new KSslErrorPrivate())
229 {
230  *d = *other.d;
231 }
232 
233 KSslError::~KSslError()
234 {
235  delete d;
236 }
237 
238 KSslError &KSslError::operator=(const KSslError &other)
239 {
240  *d = *other.d;
241  return *this;
242 }
243 
244 KSslError::Error KSslError::error() const
245 {
246  return KSslErrorPrivate::errorFromQSslError(d->error.error());
247 }
248 
249 QString KSslError::errorString() const
250 {
251  return d->error.errorString();
252 }
253 
254 QSslCertificate KSslError::certificate() const
255 {
256  return d->error.certificate();
257 }
258 
260 {
261  return d->error;
262 }
263 #endif
264 
265 class KTcpSocketPrivate
266 {
267 public:
268  explicit KTcpSocketPrivate(KTcpSocket *qq)
269  : q(qq),
270  certificatesLoaded(false),
271  emittedReadyRead(false)
272  {
273  // create the instance, which sets Qt's static internal cert set to empty.
274  KSslCertificateManager::self();
275  }
276 
277  KTcpSocket::State state(QAbstractSocket::SocketState s)
278  {
279  switch (s) {
281  return KTcpSocket::UnconnectedState;
283  return KTcpSocket::HostLookupState;
285  return KTcpSocket::ConnectingState;
287  return KTcpSocket::ConnectedState;
289  return KTcpSocket::ClosingState;
292  //### these two are not relevant as long as this can't be a server socket
293  default:
294  return KTcpSocket::UnconnectedState; //the closest to "error"
295  }
296  }
297 
298  KTcpSocket::EncryptionMode encryptionMode(QSslSocket::SslMode mode)
299  {
300  switch (mode) {
302  return KTcpSocket::SslClientMode;
304  return KTcpSocket::SslServerMode;
305  default:
306  return KTcpSocket::UnencryptedMode;
307  }
308  }
309 
310  KTcpSocket::Error errorFromAbsSocket(QAbstractSocket::SocketError e)
311  {
312  switch (e) {
314  return KTcpSocket::ConnectionRefusedError;
316  return KTcpSocket::RemoteHostClosedError;
318  return KTcpSocket::HostNotFoundError;
320  return KTcpSocket::SocketAccessError;
322  return KTcpSocket::SocketResourceError;
324  return KTcpSocket::SocketTimeoutError;
326  return KTcpSocket::NetworkError;
328  return KTcpSocket::UnsupportedSocketOperationError;
332  //we don't do UDP
335  //### own values if/when we ever get server socket support
337  //### maybe we need an enum value for this
339  default:
340  return KTcpSocket::UnknownError;
341  }
342  }
343 
344  //private slots
345  void reemitSocketError(QAbstractSocket::SocketError e)
346  {
347  q->setErrorString(sock.errorString());
348  emit q->error(errorFromAbsSocket(e));
349  }
350 
351  void reemitSslErrors(const QList<QSslError> &errors)
352  {
353  q->setErrorString(sock.errorString());
354  q->showSslErrors(); //H4X
355  QList<KSslError> kErrors;
356  kErrors.reserve(errors.size());
357  for (const QSslError &e : errors) {
358  kErrors.append(KSslError(e));
359  }
360  emit q->sslErrors(kErrors);
361  }
362 
363  void reemitStateChanged(QAbstractSocket::SocketState s)
364  {
365  emit q->stateChanged(state(s));
366  }
367 
368  void reemitModeChanged(QSslSocket::SslMode m)
369  {
370  emit q->encryptionModeChanged(encryptionMode(m));
371  }
372 
373  // This method is needed because we might emit readyRead() due to this QIODevice
374  // having some data buffered, so we need to care about blocking, too.
375  //### useless ATM as readyRead() now just calls d->sock.readyRead().
376  void reemitReadyRead()
377  {
378  if (!emittedReadyRead) {
379  emittedReadyRead = true;
380  emit q->readyRead();
381  emittedReadyRead = false;
382  }
383  }
384 
385  void maybeLoadCertificates()
386  {
387  if (!certificatesLoaded) {
388  q->setCaCertificates(KSslCertificateManager::self()->caCertificates());
389  }
390  }
391 
392  KTcpSocket *const q;
393  bool certificatesLoaded;
394  bool emittedReadyRead;
395  QSslSocket sock;
396  QList<KSslCipher> ciphers;
397  KTcpSocket::SslVersion advertisedSslVersion;
398  CipherCc ccc;
399 };
400 
401 KTcpSocket::KTcpSocket(QObject *parent)
402  : QIODevice(parent),
403  d(new KTcpSocketPrivate(this))
404 {
405  d->advertisedSslVersion = SslV3;
406 
407  connect(&d->sock, &QIODevice::aboutToClose, this, &QIODevice::aboutToClose);
408  connect(&d->sock, &QIODevice::bytesWritten, this, &QIODevice::bytesWritten);
410  connect(&d->sock, SIGNAL(readyRead()), this, SLOT(reemitReadyRead()));
411  connect(&d->sock, &QAbstractSocket::connected, this, &KTcpSocket::connected);
412  connect(&d->sock, &QSslSocket::encrypted, this, &KTcpSocket::encrypted);
413  connect(&d->sock, &QAbstractSocket::disconnected, this, &KTcpSocket::disconnected);
414 #ifndef QT_NO_NETWORKPROXY
416  this, &KTcpSocket::proxyAuthenticationRequired);
417 #endif
418  connect(&d->sock, SIGNAL(error(QAbstractSocket::SocketError)),
419  this, SLOT(reemitSocketError(QAbstractSocket::SocketError)));
420  connect(&d->sock, SIGNAL(sslErrors(QList<QSslError>)),
421  this, SLOT(reemitSslErrors(QList<QSslError>)));
422  connect(&d->sock, &QAbstractSocket::hostFound, this, &KTcpSocket::hostFound);
423  connect(&d->sock, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
424  this, SLOT(reemitStateChanged(QAbstractSocket::SocketState)));
425  connect(&d->sock, SIGNAL(modeChanged(QSslSocket::SslMode)),
426  this, SLOT(reemitModeChanged(QSslSocket::SslMode)));
427 }
428 
429 KTcpSocket::~KTcpSocket()
430 {
431  delete d;
432 }
433 
435 
436 bool KTcpSocket::atEnd() const
437 {
438  return d->sock.atEnd() && QIODevice::atEnd();
439 }
440 
441 qint64 KTcpSocket::bytesAvailable() const
442 {
443  return d->sock.bytesAvailable() + QIODevice::bytesAvailable();
444 }
445 
446 qint64 KTcpSocket::bytesToWrite() const
447 {
448  return d->sock.bytesToWrite();
449 }
450 
451 bool KTcpSocket::canReadLine() const
452 {
453  return d->sock.canReadLine() || QIODevice::canReadLine();
454 }
455 
456 void KTcpSocket::close()
457 {
458  d->sock.close();
460 }
461 
462 bool KTcpSocket::isSequential() const
463 {
464  return true;
465 }
466 
467 bool KTcpSocket::open(QIODevice::OpenMode open)
468 {
469  bool ret = d->sock.open(open);
470  setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
471  return ret;
472 }
473 
474 bool KTcpSocket::waitForBytesWritten(int msecs)
475 {
476  return d->sock.waitForBytesWritten(msecs);
477 }
478 
479 bool KTcpSocket::waitForReadyRead(int msecs)
480 {
481  return d->sock.waitForReadyRead(msecs);
482 }
483 
484 qint64 KTcpSocket::readData(char *data, qint64 maxSize)
485 {
486  return d->sock.read(data, maxSize);
487 }
488 
489 qint64 KTcpSocket::writeData(const char *data, qint64 maxSize)
490 {
491  return d->sock.write(data, maxSize);
492 }
493 
495 
496 void KTcpSocket::abort()
497 {
498  d->sock.abort();
499 }
500 
501 void KTcpSocket::connectToHost(const QString &hostName, quint16 port, ProxyPolicy policy)
502 {
503  if (policy == AutoProxy) {
504  //###
505  }
506  d->sock.connectToHost(hostName, port);
507  // there are enough layers of buffers between us and the network, and there is a quirk
508  // in QIODevice that can make it try to readData() twice per read() call if buffered and
509  // reaData() does not deliver enough data the first time. like when the other side is
510  // simply not sending any more data...
511  // this can *apparently* lead to long delays sometimes which stalls applications.
512  // do not want.
513  setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
514 }
515 
516 void KTcpSocket::connectToHost(const QHostAddress &hostAddress, quint16 port, ProxyPolicy policy)
517 {
518  if (policy == AutoProxy) {
519  //###
520  }
521  d->sock.connectToHost(hostAddress, port);
522  setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
523 }
524 
525 void KTcpSocket::connectToHost(const QUrl &url, ProxyPolicy policy)
526 {
527  if (policy == AutoProxy) {
528  //###
529  }
530  d->sock.connectToHost(url.host(), url.port());
531  setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
532 }
533 
534 void KTcpSocket::disconnectFromHost()
535 {
536  d->sock.disconnectFromHost();
537  setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
538 }
539 
540 KTcpSocket::Error KTcpSocket::error() const
541 {
542  const auto networkError = d->sock.error();
543  return d->errorFromAbsSocket(networkError);
544 }
545 
546 QList<KSslError> KTcpSocket::sslErrors() const
547 {
548  //### pretty slow; also consider throwing out duplicate error codes. We may get
549  // duplicates even though there were none in the original list because KSslError
550  // has a smallest common denominator range of SSL error codes.
551 #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
552  const auto qsslErrors = d->sock.sslHandshakeErrors();
553 #else
554  const auto qsslErrors = d->sock.sslErrors();
555 #endif
556  QList<KSslError> ret;
557  ret.reserve(qsslErrors.size());
558  for (const QSslError &e : qsslErrors) {
559  ret.append(KSslError(e));
560  }
561  return ret;
562 }
563 
564 bool KTcpSocket::flush()
565 {
566  return d->sock.flush();
567 }
568 
569 bool KTcpSocket::isValid() const
570 {
571  return d->sock.isValid();
572 }
573 
574 QHostAddress KTcpSocket::localAddress() const
575 {
576  return d->sock.localAddress();
577 }
578 
579 QHostAddress KTcpSocket::peerAddress() const
580 {
581  return d->sock.peerAddress();
582 }
583 
584 QString KTcpSocket::peerName() const
585 {
586  return d->sock.peerName();
587 }
588 
589 quint16 KTcpSocket::peerPort() const
590 {
591  return d->sock.peerPort();
592 }
593 
594 #ifndef QT_NO_NETWORKPROXY
596 {
597  return d->sock.proxy();
598 }
599 #endif
600 
601 qint64 KTcpSocket::readBufferSize() const
602 {
603  return d->sock.readBufferSize();
604 }
605 
606 #ifndef QT_NO_NETWORKPROXY
608 {
609  d->sock.setProxy(proxy);
610 }
611 #endif
612 
613 void KTcpSocket::setReadBufferSize(qint64 size)
614 {
615  d->sock.setReadBufferSize(size);
616 }
617 
618 KTcpSocket::State KTcpSocket::state() const
619 {
620  return d->state(d->sock.state());
621 }
622 
623 bool KTcpSocket::waitForConnected(int msecs)
624 {
625  bool ret = d->sock.waitForConnected(msecs);
626  if (!ret) {
627  setErrorString(d->sock.errorString());
628  }
629  setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
630  return ret;
631 }
632 
633 bool KTcpSocket::waitForDisconnected(int msecs)
634 {
635  bool ret = d->sock.waitForDisconnected(msecs);
636  if (!ret) {
637  setErrorString(d->sock.errorString());
638  }
639  setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
640  return ret;
641 }
642 
644 
645 void KTcpSocket::addCaCertificate(const QSslCertificate &certificate)
646 {
647  d->maybeLoadCertificates();
648 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
649  d->sock.addCaCertificate(certificate);
650 #else
651  d->sock.sslConfiguration().addCaCertificate(certificate);
652 #endif
653 }
654 
655 /*
656 bool KTcpSocket::addCaCertificates(const QString &path, QSsl::EncodingFormat format,
657  QRegExp::PatternSyntax syntax)
658 {
659  d->maybeLoadCertificates();
660  return d->sock.addCaCertificates(path, format, syntax);
661 }
662 */
663 
664 void KTcpSocket::addCaCertificates(const QList<QSslCertificate> &certificates)
665 {
666  d->maybeLoadCertificates();
667 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
668  d->sock.addCaCertificates(certificates);
669 #else
670  d->sock.sslConfiguration().addCaCertificates(certificates);
671 #endif
672 }
673 
674 QList<QSslCertificate> KTcpSocket::caCertificates() const
675 {
676  d->maybeLoadCertificates();
677  return d->sock.sslConfiguration().caCertificates();
678 }
679 
680 QList<KSslCipher> KTcpSocket::ciphers() const
681 {
682  return d->ciphers;
683 }
684 
685 void KTcpSocket::connectToHostEncrypted(const QString &hostName, quint16 port, OpenMode openMode)
686 {
687  d->maybeLoadCertificates();
688  d->sock.setProtocol(qSslProtocolFromK(d->advertisedSslVersion));
689  d->sock.connectToHostEncrypted(hostName, port, openMode);
690  setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
691 }
692 
693 QSslCertificate KTcpSocket::localCertificate() const
694 {
695  return d->sock.localCertificate();
696 }
697 
698 QList<QSslCertificate> KTcpSocket::peerCertificateChain() const
699 {
700  return d->sock.peerCertificateChain();
701 }
702 
703 KSslKey KTcpSocket::privateKey() const
704 {
705  return KSslKey(d->sock.privateKey());
706 }
707 
708 KSslCipher KTcpSocket::sessionCipher() const
709 {
710  return KSslCipher(d->sock.sessionCipher());
711 }
712 
713 void KTcpSocket::setCaCertificates(const QList<QSslCertificate> &certificates)
714 {
715  QSslConfiguration configuration = d->sock.sslConfiguration();
716  configuration.setCaCertificates(certificates);
717  d->sock.setSslConfiguration(configuration);
718  d->certificatesLoaded = true;
719 }
720 
721 void KTcpSocket::setCiphers(const QList<KSslCipher> &ciphers)
722 {
723  d->ciphers = ciphers;
725  cl.reserve(d->ciphers.size());
726  for (const KSslCipher &c : ciphers) {
727  cl.append(d->ccc.converted(c));
728  }
729  QSslConfiguration configuration = d->sock.sslConfiguration();
730  configuration.setCiphers(cl);
731  d->sock.setSslConfiguration(configuration);
732 }
733 
734 void KTcpSocket::setLocalCertificate(const QSslCertificate &certificate)
735 {
736  d->sock.setLocalCertificate(certificate);
737 }
738 
739 void KTcpSocket::setLocalCertificate(const QString &fileName, QSsl::EncodingFormat format)
740 {
741  d->sock.setLocalCertificate(fileName, format);
742 }
743 
744 void KTcpSocket::setVerificationPeerName(const QString &hostName)
745 {
746  d->sock.setPeerVerifyName(hostName);
747 }
748 
749 void KTcpSocket::setPrivateKey(const KSslKey &key)
750 {
751  // We cannot map KSslKey::Algorithm:Dh to anything in QSsl::KeyAlgorithm.
752  if (key.algorithm() == KSslKey::Dh) {
753  return;
754  }
755 
756  QSslKey _key(key.toDer(),
757  (key.algorithm() == KSslKey::Rsa) ? QSsl::Rsa : QSsl::Dsa,
758  QSsl::Der,
759  (key.secrecy() == KSslKey::PrivateKey) ? QSsl::PrivateKey : QSsl::PublicKey);
760 
761  d->sock.setPrivateKey(_key);
762 }
763 
764 void KTcpSocket::setPrivateKey(const QString &fileName, KSslKey::Algorithm algorithm,
765  QSsl::EncodingFormat format, const QByteArray &passPhrase)
766 {
767  // We cannot map KSslKey::Algorithm:Dh to anything in QSsl::KeyAlgorithm.
768  if (algorithm == KSslKey::Dh) {
769  return;
770  }
771 
772  d->sock.setPrivateKey(fileName,
773  (algorithm == KSslKey::Rsa) ? QSsl::Rsa : QSsl::Dsa,
774  format,
775  passPhrase);
776 }
777 
778 bool KTcpSocket::waitForEncrypted(int msecs)
779 {
780  return d->sock.waitForEncrypted(msecs);
781 }
782 
783 KTcpSocket::EncryptionMode KTcpSocket::encryptionMode() const
784 {
785  return d->encryptionMode(d->sock.mode());
786 }
787 
789 {
790  return d->sock.socketOption(options);
791 }
792 
794 {
795  d->sock.setSocketOption(options, value);
796 }
797 
799 {
800  return d->sock.sslConfiguration();
801 }
802 
804 {
805  d->sock.setSslConfiguration(configuration);
806 }
807 
808 //slot
809 void KTcpSocket::ignoreSslErrors()
810 {
811  d->sock.ignoreSslErrors();
812 }
813 
814 //slot
815 void KTcpSocket::startClientEncryption()
816 {
817  d->maybeLoadCertificates();
818  d->sock.setProtocol(qSslProtocolFromK(d->advertisedSslVersion));
819  d->sock.startClientEncryption();
820 }
821 
822 //debugging H4X
823 void KTcpSocket::showSslErrors()
824 {
825 #if (QT_VERSION < QT_VERSION_CHECK(5, 15, 0))
826  const QList<QSslError> list = d->sock.sslErrors();
827 #else
828  const QList<QSslError> list = d->sock.sslHandshakeErrors();
829 #endif
830  for (const QSslError &e : list) {
831  qCDebug(KIO_CORE) << e.errorString();
832  }
833 }
834 
835 void KTcpSocket::setAdvertisedSslVersion(KTcpSocket::SslVersion version)
836 {
837  d->advertisedSslVersion = version;
838 }
839 
840 KTcpSocket::SslVersion KTcpSocket::advertisedSslVersion() const
841 {
842  return d->advertisedSslVersion;
843 }
844 
845 KTcpSocket::SslVersion KTcpSocket::negotiatedSslVersion() const
846 {
847  if (!d->sock.isEncrypted()) {
848  return UnknownSslVersion;
849  }
850 
851  return kSslVersionFromQ(d->sock.sessionProtocol());
852 }
853 
854 QString KTcpSocket::negotiatedSslVersionName() const
855 {
856  if (!d->sock.isEncrypted()) {
857  return QString();
858  }
859 
860  return protocolString(d->sock.sessionProtocol());
861 }
862 
864 
865 class KSslKeyPrivate
866 {
867 public:
868  KSslKey::Algorithm convertAlgorithm(QSsl::KeyAlgorithm a)
869  {
870  switch (a) {
871  case QSsl::Dsa:
872  return KSslKey::Dsa;
873  default:
874  return KSslKey::Rsa;
875  }
876  }
877 
878  KSslKey::Algorithm algorithm;
879  KSslKey::KeySecrecy secrecy;
880  bool isExportable;
881  QByteArray der;
882 };
883 
884 KSslKey::KSslKey()
885  : d(new KSslKeyPrivate)
886 {
887  d->algorithm = Rsa;
888  d->secrecy = PublicKey;
889  d->isExportable = true;
890 }
891 
892 KSslKey::KSslKey(const KSslKey &other)
893  : d(new KSslKeyPrivate)
894 {
895  *d = *other.d;
896 }
897 
898 KSslKey::KSslKey(const QSslKey &qsk)
899  : d(new KSslKeyPrivate)
900 {
901  d->algorithm = d->convertAlgorithm(qsk.algorithm());
902  d->secrecy = (qsk.type() == QSsl::PrivateKey) ? PrivateKey : PublicKey;
903  d->isExportable = true;
904  d->der = qsk.toDer();
905 }
906 
907 KSslKey::~KSslKey()
908 {
909  delete d;
910 }
911 
912 KSslKey &KSslKey::operator=(const KSslKey &other)
913 {
914  *d = *other.d;
915  return *this;
916 }
917 
918 KSslKey::Algorithm KSslKey::algorithm() const
919 {
920  return d->algorithm;
921 }
922 
923 bool KSslKey::isExportable() const
924 {
925  return d->isExportable;
926 }
927 
928 KSslKey::KeySecrecy KSslKey::secrecy() const
929 {
930  return d->secrecy;
931 }
932 
933 QByteArray KSslKey::toDer() const
934 {
935  return d->der;
936 }
937 
939 
940 //nice-to-have: make implicitly shared
941 class KSslCipherPrivate
942 {
943 public:
944 
945  QString authenticationMethod;
946  QString encryptionMethod;
947  QString keyExchangeMethod;
948  QString name;
949  bool isNull;
950  int supportedBits;
951  int usedBits;
952 };
953 
954 KSslCipher::KSslCipher()
955  : d(new KSslCipherPrivate)
956 {
957  d->isNull = true;
958  d->supportedBits = 0;
959  d->usedBits = 0;
960 }
961 
962 KSslCipher::KSslCipher(const KSslCipher &other)
963  : d(new KSslCipherPrivate)
964 {
965  *d = *other.d;
966 }
967 
968 KSslCipher::KSslCipher(const QSslCipher &qsc)
969  : d(new KSslCipherPrivate)
970 {
971  d->authenticationMethod = qsc.authenticationMethod();
972  d->encryptionMethod = qsc.encryptionMethod();
973  //Qt likes to append the number of bits (usedBits?) to the algorithm,
974  //for example "AES(256)". We only want the pure algorithm name, though.
975  int parenIdx = d->encryptionMethod.indexOf(QLatin1Char('('));
976  if (parenIdx > 0) {
977  d->encryptionMethod.truncate(parenIdx);
978  }
979  d->keyExchangeMethod = qsc.keyExchangeMethod();
980  d->name = qsc.name();
981  d->isNull = qsc.isNull();
982  d->supportedBits = qsc.supportedBits();
983  d->usedBits = qsc.usedBits();
984 }
985 
986 KSslCipher::~KSslCipher()
987 {
988  delete d;
989 }
990 
991 KSslCipher &KSslCipher::operator=(const KSslCipher &other)
992 {
993  *d = *other.d;
994  return *this;
995 }
996 
997 bool KSslCipher::isNull() const
998 {
999  return d->isNull;
1000 }
1001 
1002 QString KSslCipher::authenticationMethod() const
1003 {
1004  return d->authenticationMethod;
1005 }
1006 
1007 QString KSslCipher::encryptionMethod() const
1008 {
1009  return d->encryptionMethod;
1010 }
1011 
1012 QString KSslCipher::keyExchangeMethod() const
1013 {
1014  return d->keyExchangeMethod;
1015 }
1016 
1017 QString KSslCipher::digestMethod() const
1018 {
1019  //### This is not really backend neutral. It works for OpenSSL and
1020  // for RFC compliant names, though.
1021  if (d->name.endsWith(QLatin1String("SHA"))) {
1022  return QStringLiteral("SHA-1");
1023  } else if (d->name.endsWith(QLatin1String("MD5"))) {
1024  return QStringLiteral("MD5");
1025  } else {
1026  return QString();
1027  }
1028 }
1029 
1030 QString KSslCipher::name() const
1031 {
1032  return d->name;
1033 }
1034 
1035 int KSslCipher::supportedBits() const
1036 {
1037  return d->supportedBits;
1038 }
1039 
1040 int KSslCipher::usedBits() const
1041 {
1042  return d->usedBits;
1043 }
1044 
1045 //static
1046 QList<KSslCipher> KSslCipher::supportedCiphers()
1047 {
1048  QList<KSslCipher> ret;
1050  ret.reserve(candidates.size());
1051  for (const QSslCipher &c : candidates) {
1052  ret.append(KSslCipher(c));
1053  }
1054  return ret;
1055 }
1056 
1057 #include "moc_ktcpsocket.cpp"
1058 
1059 #endif
QSsl::KeyType type() const const
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
virtual bool atEnd() const const
int supportedBits() const const
void reserve(int alloc)
void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
QString host(QUrl::ComponentFormattingOptions options) const const
void aboutToClose()
void encryptedBytesWritten(qint64 written)
typedef OpenMode
void setCiphers(const QList< QSslCipher > &ciphers)
SSL Cipher.
Definition: ktcpsocket.h:67
int port(int defaultPort) const const
virtual void close()
QString authenticationMethod() const const
int size() const const
bool isNull() const const
SSL Key.
Definition: ktcpsocket.h:35
TCP socket.
Definition: ktcpsocket.h:155
QVariant socketOption(QAbstractSocket::SocketOption options) const
Returns the state of the socket option.
Definition: ktcpsocket.cpp:788
void setCaCertificates(const QList< QSslCertificate > &certificates)
QSslError sslError() const
Returns the QSslError wrapped by this KSslError.
Definition: ktcpsocket.cpp:259
void append(const T &value)
QString keyExchangeMethod() const const
QSsl::KeyAlgorithm algorithm() const const
KSslError(KSslError::Error error=NoError, const QSslCertificate &cert=QSslCertificate())
Definition: ktcpsocket.cpp:215
void setSslConfiguration(const QSslConfiguration &configuration)
Sets the socket&#39;s SSL configuration.
Definition: ktcpsocket.cpp:803
void setSocketOption(QAbstractSocket::SocketOption options, const QVariant &value)
Sets the socket option to value.
Definition: ktcpsocket.cpp:793
void bytesWritten(qint64 bytes)
QList< QSslCipher > supportedCiphers()
virtual qint64 bytesAvailable() const const
QByteArray toDer(const QByteArray &passPhrase) const const
void setProxy(const QNetworkProxy &proxy)
Definition: ktcpsocket.cpp:607
QNetworkProxy proxy() const
Definition: ktcpsocket.cpp:595
int open(const QString &pathname, int flags, mode_t mode=0)
void encryptedBytesWritten(qint64 written)
EncodingFormat
QString name() const const
To be replaced by QSslError.
Definition: ktcpsocket.h:98
bool isNull() const const
void encrypted()
virtual bool canReadLine() const const
QString encryptionMethod() const const
QSslConfiguration sslConfiguration() const
Returns the socket&#39;s SSL configuration.
Definition: ktcpsocket.cpp:798
int usedBits() const const
KIOFILEWIDGETS_EXPORT QStringList list(const QString &fileClass)
Returns a list of directories associated with this file-class.
Definition: krecentdirs.cpp:34
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Oct 19 2020 23:06:42 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.