File indexing completed on 2024-05-05 12:18:17
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2007, 2008 Andreas Hartmetz <ahartmetz@gmail.com> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "ktcpsocket.h" 0009 #include "kiocoredebug.h" 0010 #include "ksslerror_p.h" 0011 0012 #include <KLocalizedString> 0013 #include <ksslcertificatemanager.h> 0014 0015 #include <QAbstractSocket> 0016 #include <QAuthenticator> 0017 #include <QHostAddress> 0018 #include <QNetworkProxy> 0019 #include <QSslCipher> 0020 #include <QSslKey> 0021 #include <QUrl> 0022 0023 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 65) 0024 0025 static KTcpSocket::SslVersion kSslVersionFromQ(QSsl::SslProtocol protocol) 0026 { 0027 switch (protocol) { 0028 case QSsl::TlsV1_0: 0029 return KTcpSocket::TlsV1; 0030 case QSsl::TlsV1_1: 0031 return KTcpSocket::TlsV1_1; 0032 case QSsl::TlsV1_2: 0033 return KTcpSocket::TlsV1_2; 0034 case QSsl::TlsV1_3: 0035 return KTcpSocket::TlsV1_3; 0036 case QSsl::AnyProtocol: 0037 return KTcpSocket::AnySslVersion; 0038 case QSsl::SecureProtocols: 0039 return KTcpSocket::SecureProtocols; 0040 default: 0041 return KTcpSocket::UnknownSslVersion; 0042 } 0043 } 0044 0045 static QSsl::SslProtocol qSslProtocolFromK(KTcpSocket::SslVersion sslVersion) 0046 { 0047 // ### this lowlevel bit-banging is a little dangerous and a likely source of bugs 0048 if (sslVersion == KTcpSocket::AnySslVersion) { 0049 return QSsl::AnyProtocol; 0050 } 0051 // does it contain any valid protocol? 0052 KTcpSocket::SslVersions validVersions(KTcpSocket::TlsV1); 0053 validVersions |= KTcpSocket::TlsV1_1; 0054 validVersions |= KTcpSocket::TlsV1_2; 0055 validVersions |= KTcpSocket::TlsV1_3; 0056 validVersions |= KTcpSocket::SecureProtocols; 0057 0058 if (!(sslVersion & validVersions)) { 0059 return QSsl::UnknownProtocol; 0060 } 0061 0062 switch (sslVersion) { 0063 case KTcpSocket::TlsV1_0: 0064 return QSsl::TlsV1_0; 0065 case KTcpSocket::TlsV1_1: 0066 return QSsl::TlsV1_1; 0067 case KTcpSocket::TlsV1_2: 0068 return QSsl::TlsV1_2; 0069 case KTcpSocket::TlsV1_3: 0070 return QSsl::TlsV1_3; 0071 case KTcpSocket::SecureProtocols: 0072 return QSsl::SecureProtocols; 0073 0074 default: 0075 // QSslSocket doesn't really take arbitrary combinations. It's one or all. 0076 return QSsl::AnyProtocol; 0077 } 0078 } 0079 0080 static QString protocolString(QSsl::SslProtocol protocol) 0081 { 0082 switch (protocol) { 0083 case QSsl::TlsV1_0: 0084 return QStringLiteral("TLSv1.0"); 0085 case QSsl::TlsV1_1: 0086 return QStringLiteral("TLSv1.1"); 0087 case QSsl::TlsV1_2: 0088 return QStringLiteral("TLSv1.2"); 0089 case QSsl::TlsV1_3: 0090 return QStringLiteral("TLSv1.3"); 0091 default: 0092 return QStringLiteral("Unknown"); 0093 ; 0094 } 0095 } 0096 0097 // cipher class converter KSslCipher -> QSslCipher 0098 class CipherCc 0099 { 0100 public: 0101 CipherCc() 0102 { 0103 const QList<QSslCipher> list = QSslConfiguration::supportedCiphers(); 0104 for (const QSslCipher &c : list) { 0105 allCiphers.insert(c.name(), c); 0106 } 0107 } 0108 0109 QSslCipher converted(const KSslCipher &ksc) 0110 { 0111 return allCiphers.value(ksc.name()); 0112 } 0113 0114 private: 0115 QHash<QString, QSslCipher> allCiphers; 0116 }; 0117 0118 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 65) 0119 KSslError::Error KSslErrorPrivate::errorFromQSslError(QSslError::SslError e) 0120 { 0121 switch (e) { 0122 case QSslError::NoError: 0123 return KSslError::NoError; 0124 case QSslError::UnableToGetLocalIssuerCertificate: 0125 case QSslError::InvalidCaCertificate: 0126 return KSslError::InvalidCertificateAuthorityCertificate; 0127 case QSslError::InvalidNotBeforeField: 0128 case QSslError::InvalidNotAfterField: 0129 case QSslError::CertificateNotYetValid: 0130 case QSslError::CertificateExpired: 0131 return KSslError::ExpiredCertificate; 0132 case QSslError::UnableToDecodeIssuerPublicKey: 0133 case QSslError::SubjectIssuerMismatch: 0134 case QSslError::AuthorityIssuerSerialNumberMismatch: 0135 return KSslError::InvalidCertificate; 0136 case QSslError::SelfSignedCertificate: 0137 case QSslError::SelfSignedCertificateInChain: 0138 return KSslError::SelfSignedCertificate; 0139 case QSslError::CertificateRevoked: 0140 return KSslError::RevokedCertificate; 0141 case QSslError::InvalidPurpose: 0142 return KSslError::InvalidCertificatePurpose; 0143 case QSslError::CertificateUntrusted: 0144 return KSslError::UntrustedCertificate; 0145 case QSslError::CertificateRejected: 0146 return KSslError::RejectedCertificate; 0147 case QSslError::NoPeerCertificate: 0148 return KSslError::NoPeerCertificate; 0149 case QSslError::HostNameMismatch: 0150 return KSslError::HostNameMismatch; 0151 case QSslError::UnableToVerifyFirstCertificate: 0152 case QSslError::UnableToDecryptCertificateSignature: 0153 case QSslError::UnableToGetIssuerCertificate: 0154 case QSslError::CertificateSignatureFailed: 0155 return KSslError::CertificateSignatureFailed; 0156 case QSslError::PathLengthExceeded: 0157 return KSslError::PathLengthExceeded; 0158 case QSslError::UnspecifiedError: 0159 case QSslError::NoSslSupport: 0160 default: 0161 return KSslError::UnknownError; 0162 } 0163 } 0164 0165 QSslError::SslError KSslErrorPrivate::errorFromKSslError(KSslError::Error e) 0166 { 0167 switch (e) { 0168 case KSslError::NoError: 0169 return QSslError::NoError; 0170 case KSslError::InvalidCertificateAuthorityCertificate: 0171 return QSslError::InvalidCaCertificate; 0172 case KSslError::InvalidCertificate: 0173 return QSslError::UnableToDecodeIssuerPublicKey; 0174 case KSslError::CertificateSignatureFailed: 0175 return QSslError::CertificateSignatureFailed; 0176 case KSslError::SelfSignedCertificate: 0177 return QSslError::SelfSignedCertificate; 0178 case KSslError::ExpiredCertificate: 0179 return QSslError::CertificateExpired; 0180 case KSslError::RevokedCertificate: 0181 return QSslError::CertificateRevoked; 0182 case KSslError::InvalidCertificatePurpose: 0183 return QSslError::InvalidPurpose; 0184 case KSslError::RejectedCertificate: 0185 return QSslError::CertificateRejected; 0186 case KSslError::UntrustedCertificate: 0187 return QSslError::CertificateUntrusted; 0188 case KSslError::NoPeerCertificate: 0189 return QSslError::NoPeerCertificate; 0190 case KSslError::HostNameMismatch: 0191 return QSslError::HostNameMismatch; 0192 case KSslError::PathLengthExceeded: 0193 return QSslError::PathLengthExceeded; 0194 case KSslError::UnknownError: 0195 default: 0196 return QSslError::UnspecifiedError; 0197 } 0198 } 0199 0200 KSslError::KSslError(Error errorCode, const QSslCertificate &certificate) 0201 : d(new KSslErrorPrivate()) 0202 { 0203 d->error = QSslError(d->errorFromKSslError(errorCode), certificate); 0204 } 0205 0206 KSslError::KSslError(const QSslError &other) 0207 : d(new KSslErrorPrivate()) 0208 { 0209 d->error = other; 0210 } 0211 0212 KSslError::KSslError(const KSslError &other) 0213 : d(new KSslErrorPrivate()) 0214 { 0215 *d = *other.d; 0216 } 0217 0218 KSslError::~KSslError() = default; 0219 0220 KSslError &KSslError::operator=(const KSslError &other) 0221 { 0222 *d = *other.d; 0223 return *this; 0224 } 0225 0226 KSslError::Error KSslError::error() const 0227 { 0228 return KSslErrorPrivate::errorFromQSslError(d->error.error()); 0229 } 0230 0231 QString KSslError::errorString() const 0232 { 0233 return d->error.errorString(); 0234 } 0235 0236 QSslCertificate KSslError::certificate() const 0237 { 0238 return d->error.certificate(); 0239 } 0240 0241 QSslError KSslError::sslError() const 0242 { 0243 return d->error; 0244 } 0245 #endif 0246 0247 class KTcpSocketPrivate 0248 { 0249 public: 0250 explicit KTcpSocketPrivate(KTcpSocket *qq) 0251 : q(qq) 0252 , certificatesLoaded(false) 0253 , emittedReadyRead(false) 0254 { 0255 // create the instance, which sets Qt's static internal cert set to empty. 0256 KSslCertificateManager::self(); 0257 } 0258 0259 KTcpSocket::State state(QAbstractSocket::SocketState s) 0260 { 0261 switch (s) { 0262 case QAbstractSocket::UnconnectedState: 0263 return KTcpSocket::UnconnectedState; 0264 case QAbstractSocket::HostLookupState: 0265 return KTcpSocket::HostLookupState; 0266 case QAbstractSocket::ConnectingState: 0267 return KTcpSocket::ConnectingState; 0268 case QAbstractSocket::ConnectedState: 0269 return KTcpSocket::ConnectedState; 0270 case QAbstractSocket::ClosingState: 0271 return KTcpSocket::ClosingState; 0272 case QAbstractSocket::BoundState: 0273 case QAbstractSocket::ListeningState: 0274 // ### these two are not relevant as long as this can't be a server socket 0275 default: 0276 return KTcpSocket::UnconnectedState; // the closest to "error" 0277 } 0278 } 0279 0280 KTcpSocket::EncryptionMode encryptionMode(QSslSocket::SslMode mode) 0281 { 0282 switch (mode) { 0283 case QSslSocket::SslClientMode: 0284 return KTcpSocket::SslClientMode; 0285 case QSslSocket::SslServerMode: 0286 return KTcpSocket::SslServerMode; 0287 default: 0288 return KTcpSocket::UnencryptedMode; 0289 } 0290 } 0291 0292 KTcpSocket::Error errorFromAbsSocket(QAbstractSocket::SocketError e) 0293 { 0294 switch (e) { 0295 case QAbstractSocket::ConnectionRefusedError: 0296 return KTcpSocket::ConnectionRefusedError; 0297 case QAbstractSocket::RemoteHostClosedError: 0298 return KTcpSocket::RemoteHostClosedError; 0299 case QAbstractSocket::HostNotFoundError: 0300 return KTcpSocket::HostNotFoundError; 0301 case QAbstractSocket::SocketAccessError: 0302 return KTcpSocket::SocketAccessError; 0303 case QAbstractSocket::SocketResourceError: 0304 return KTcpSocket::SocketResourceError; 0305 case QAbstractSocket::SocketTimeoutError: 0306 return KTcpSocket::SocketTimeoutError; 0307 case QAbstractSocket::NetworkError: 0308 return KTcpSocket::NetworkError; 0309 case QAbstractSocket::UnsupportedSocketOperationError: 0310 return KTcpSocket::UnsupportedSocketOperationError; 0311 case QAbstractSocket::SslHandshakeFailedError: 0312 return KTcpSocket::SslHandshakeFailedError; 0313 case QAbstractSocket::DatagramTooLargeError: 0314 // we don't do UDP 0315 case QAbstractSocket::AddressInUseError: 0316 case QAbstractSocket::SocketAddressNotAvailableError: 0317 // ### own values if/when we ever get server socket support 0318 case QAbstractSocket::ProxyAuthenticationRequiredError: 0319 // ### maybe we need an enum value for this 0320 case QAbstractSocket::UnknownSocketError: 0321 default: 0322 return KTcpSocket::UnknownError; 0323 } 0324 } 0325 0326 // private slots 0327 void reemitSocketError(QAbstractSocket::SocketError e) 0328 { 0329 q->setErrorString(sock.errorString()); 0330 Q_EMIT q->error(errorFromAbsSocket(e)); 0331 } 0332 0333 void reemitSslErrors(const QList<QSslError> &errors) 0334 { 0335 q->setErrorString(sock.errorString()); 0336 q->showSslErrors(); // H4X 0337 QList<KSslError> kErrors; 0338 kErrors.reserve(errors.size()); 0339 for (const QSslError &e : errors) { 0340 kErrors.append(KSslError(e)); 0341 } 0342 Q_EMIT q->sslErrors(kErrors); 0343 } 0344 0345 void reemitStateChanged(QAbstractSocket::SocketState s) 0346 { 0347 Q_EMIT q->stateChanged(state(s)); 0348 } 0349 0350 void reemitModeChanged(QSslSocket::SslMode m) 0351 { 0352 Q_EMIT q->encryptionModeChanged(encryptionMode(m)); 0353 } 0354 0355 // This method is needed because we might emit readyRead() due to this QIODevice 0356 // having some data buffered, so we need to care about blocking, too. 0357 // ### useless ATM as readyRead() now just calls d->sock.readyRead(). 0358 void reemitReadyRead() 0359 { 0360 if (!emittedReadyRead) { 0361 emittedReadyRead = true; 0362 Q_EMIT q->readyRead(); 0363 emittedReadyRead = false; 0364 } 0365 } 0366 0367 void maybeLoadCertificates() 0368 { 0369 if (!certificatesLoaded) { 0370 q->setCaCertificates(KSslCertificateManager::self()->caCertificates()); 0371 } 0372 } 0373 0374 KTcpSocket *const q; 0375 bool certificatesLoaded; 0376 bool emittedReadyRead; 0377 QSslSocket sock; 0378 QList<KSslCipher> ciphers; 0379 KTcpSocket::SslVersion advertisedSslVersion; 0380 CipherCc ccc; 0381 }; 0382 0383 KTcpSocket::KTcpSocket(QObject *parent) 0384 : QIODevice(parent) 0385 , d(new KTcpSocketPrivate(this)) 0386 { 0387 d->advertisedSslVersion = SslV3; 0388 0389 connect(&d->sock, &QIODevice::aboutToClose, this, &QIODevice::aboutToClose); 0390 connect(&d->sock, &QIODevice::bytesWritten, this, &QIODevice::bytesWritten); 0391 connect(&d->sock, &QSslSocket::encryptedBytesWritten, this, &KTcpSocket::encryptedBytesWritten); 0392 connect(&d->sock, &QSslSocket::readyRead, this, [this]() { 0393 d->reemitReadyRead(); 0394 }); 0395 connect(&d->sock, &QAbstractSocket::connected, this, &KTcpSocket::connected); 0396 connect(&d->sock, &QSslSocket::encrypted, this, &KTcpSocket::encrypted); 0397 connect(&d->sock, &QAbstractSocket::disconnected, this, &KTcpSocket::disconnected); 0398 #ifndef QT_NO_NETWORKPROXY 0399 connect(&d->sock, &QAbstractSocket::proxyAuthenticationRequired, this, &KTcpSocket::proxyAuthenticationRequired); 0400 #endif 0401 0402 connect(&d->sock, &QSslSocket::errorOccurred, this, [this](QAbstractSocket::SocketError err) { 0403 d->reemitSocketError(err); 0404 }); 0405 0406 connect(&d->sock, qOverload<const QList<QSslError> &>(&QSslSocket::sslErrors), this, [this](const QList<QSslError> &errorList) { 0407 d->reemitSslErrors(errorList); 0408 }); 0409 connect(&d->sock, &QAbstractSocket::hostFound, this, &KTcpSocket::hostFound); 0410 connect(&d->sock, &QSslSocket::stateChanged, this, [this](QAbstractSocket::SocketState state) { 0411 d->reemitStateChanged(state); 0412 }); 0413 connect(&d->sock, &QSslSocket::modeChanged, this, [this](QSslSocket::SslMode mode) { 0414 d->reemitModeChanged(mode); 0415 }); 0416 } 0417 0418 KTcpSocket::~KTcpSocket() 0419 { 0420 // Cleanup before ~KTcpSocketPrivate does that with d being null (on libc++) 0421 // (stateChanged will be emitted, and the above slots use 'd') 0422 abort(); 0423 } 0424 0425 ////////////////////////////// (mostly) virtuals from QIODevice 0426 0427 bool KTcpSocket::atEnd() const 0428 { 0429 return d->sock.atEnd() && QIODevice::atEnd(); 0430 } 0431 0432 qint64 KTcpSocket::bytesAvailable() const 0433 { 0434 return d->sock.bytesAvailable() + QIODevice::bytesAvailable(); 0435 } 0436 0437 qint64 KTcpSocket::bytesToWrite() const 0438 { 0439 return d->sock.bytesToWrite(); 0440 } 0441 0442 bool KTcpSocket::canReadLine() const 0443 { 0444 return d->sock.canReadLine() || QIODevice::canReadLine(); 0445 } 0446 0447 void KTcpSocket::close() 0448 { 0449 d->sock.close(); 0450 QIODevice::close(); 0451 } 0452 0453 bool KTcpSocket::isSequential() const 0454 { 0455 return true; 0456 } 0457 0458 bool KTcpSocket::open(QIODevice::OpenMode open) 0459 { 0460 bool ret = d->sock.open(open); 0461 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered); 0462 return ret; 0463 } 0464 0465 bool KTcpSocket::waitForBytesWritten(int msecs) 0466 { 0467 return d->sock.waitForBytesWritten(msecs); 0468 } 0469 0470 bool KTcpSocket::waitForReadyRead(int msecs) 0471 { 0472 return d->sock.waitForReadyRead(msecs); 0473 } 0474 0475 qint64 KTcpSocket::readData(char *data, qint64 maxSize) 0476 { 0477 return d->sock.read(data, maxSize); 0478 } 0479 0480 qint64 KTcpSocket::writeData(const char *data, qint64 maxSize) 0481 { 0482 return d->sock.write(data, maxSize); 0483 } 0484 0485 ////////////////////////////// public methods from QAbstractSocket 0486 0487 void KTcpSocket::abort() 0488 { 0489 d->sock.abort(); 0490 } 0491 0492 void KTcpSocket::connectToHost(const QString &hostName, quint16 port, ProxyPolicy policy) 0493 { 0494 if (policy == AutoProxy) { 0495 // ### 0496 } 0497 d->sock.connectToHost(hostName, port); 0498 // there are enough layers of buffers between us and the network, and there is a quirk 0499 // in QIODevice that can make it try to readData() twice per read() call if buffered and 0500 // reaData() does not deliver enough data the first time. like when the other side is 0501 // simply not sending any more data... 0502 // this can *apparently* lead to long delays sometimes which stalls applications. 0503 // do not want. 0504 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered); 0505 } 0506 0507 void KTcpSocket::connectToHost(const QHostAddress &hostAddress, quint16 port, ProxyPolicy policy) 0508 { 0509 if (policy == AutoProxy) { 0510 // ### 0511 } 0512 d->sock.connectToHost(hostAddress, port); 0513 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered); 0514 } 0515 0516 void KTcpSocket::connectToHost(const QUrl &url, ProxyPolicy policy) 0517 { 0518 if (policy == AutoProxy) { 0519 // ### 0520 } 0521 d->sock.connectToHost(url.host(), url.port()); 0522 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered); 0523 } 0524 0525 void KTcpSocket::disconnectFromHost() 0526 { 0527 d->sock.disconnectFromHost(); 0528 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered); 0529 } 0530 0531 KTcpSocket::Error KTcpSocket::error() const 0532 { 0533 const auto networkError = d->sock.error(); 0534 return d->errorFromAbsSocket(networkError); 0535 } 0536 0537 QList<KSslError> KTcpSocket::sslErrors() const 0538 { 0539 // ### pretty slow; also consider throwing out duplicate error codes. We may get 0540 // duplicates even though there were none in the original list because KSslError 0541 // has a smallest common denominator range of SSL error codes. 0542 const auto qsslErrors = d->sock.sslHandshakeErrors(); 0543 QList<KSslError> ret; 0544 ret.reserve(qsslErrors.size()); 0545 for (const QSslError &e : qsslErrors) { 0546 ret.append(KSslError(e)); 0547 } 0548 return ret; 0549 } 0550 0551 bool KTcpSocket::flush() 0552 { 0553 return d->sock.flush(); 0554 } 0555 0556 bool KTcpSocket::isValid() const 0557 { 0558 return d->sock.isValid(); 0559 } 0560 0561 QHostAddress KTcpSocket::localAddress() const 0562 { 0563 return d->sock.localAddress(); 0564 } 0565 0566 QHostAddress KTcpSocket::peerAddress() const 0567 { 0568 return d->sock.peerAddress(); 0569 } 0570 0571 QString KTcpSocket::peerName() const 0572 { 0573 return d->sock.peerName(); 0574 } 0575 0576 quint16 KTcpSocket::peerPort() const 0577 { 0578 return d->sock.peerPort(); 0579 } 0580 0581 #ifndef QT_NO_NETWORKPROXY 0582 QNetworkProxy KTcpSocket::proxy() const 0583 { 0584 return d->sock.proxy(); 0585 } 0586 #endif 0587 0588 qint64 KTcpSocket::readBufferSize() const 0589 { 0590 return d->sock.readBufferSize(); 0591 } 0592 0593 #ifndef QT_NO_NETWORKPROXY 0594 void KTcpSocket::setProxy(const QNetworkProxy &proxy) 0595 { 0596 d->sock.setProxy(proxy); 0597 } 0598 #endif 0599 0600 void KTcpSocket::setReadBufferSize(qint64 size) 0601 { 0602 d->sock.setReadBufferSize(size); 0603 } 0604 0605 KTcpSocket::State KTcpSocket::state() const 0606 { 0607 return d->state(d->sock.state()); 0608 } 0609 0610 bool KTcpSocket::waitForConnected(int msecs) 0611 { 0612 bool ret = d->sock.waitForConnected(msecs); 0613 if (!ret) { 0614 setErrorString(d->sock.errorString()); 0615 } 0616 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered); 0617 return ret; 0618 } 0619 0620 bool KTcpSocket::waitForDisconnected(int msecs) 0621 { 0622 bool ret = d->sock.waitForDisconnected(msecs); 0623 if (!ret) { 0624 setErrorString(d->sock.errorString()); 0625 } 0626 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered); 0627 return ret; 0628 } 0629 0630 ////////////////////////////// public methods from QSslSocket 0631 0632 void KTcpSocket::addCaCertificate(const QSslCertificate &certificate) 0633 { 0634 d->maybeLoadCertificates(); 0635 d->sock.sslConfiguration().addCaCertificate(certificate); 0636 } 0637 0638 /* 0639 bool KTcpSocket::addCaCertificates(const QString &path, QSsl::EncodingFormat format, 0640 QRegExp::PatternSyntax syntax) 0641 { 0642 d->maybeLoadCertificates(); 0643 return d->sock.addCaCertificates(path, format, syntax); 0644 } 0645 */ 0646 0647 void KTcpSocket::addCaCertificates(const QList<QSslCertificate> &certificates) 0648 { 0649 d->maybeLoadCertificates(); 0650 d->sock.sslConfiguration().addCaCertificates(certificates); 0651 } 0652 0653 QList<QSslCertificate> KTcpSocket::caCertificates() const 0654 { 0655 d->maybeLoadCertificates(); 0656 return d->sock.sslConfiguration().caCertificates(); 0657 } 0658 0659 QList<KSslCipher> KTcpSocket::ciphers() const 0660 { 0661 return d->ciphers; 0662 } 0663 0664 void KTcpSocket::connectToHostEncrypted(const QString &hostName, quint16 port, OpenMode openMode) 0665 { 0666 d->maybeLoadCertificates(); 0667 d->sock.setProtocol(qSslProtocolFromK(d->advertisedSslVersion)); 0668 d->sock.connectToHostEncrypted(hostName, port, openMode); 0669 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered); 0670 } 0671 0672 QSslCertificate KTcpSocket::localCertificate() const 0673 { 0674 return d->sock.localCertificate(); 0675 } 0676 0677 QList<QSslCertificate> KTcpSocket::peerCertificateChain() const 0678 { 0679 return d->sock.peerCertificateChain(); 0680 } 0681 0682 KSslKey KTcpSocket::privateKey() const 0683 { 0684 return KSslKey(d->sock.privateKey()); 0685 } 0686 0687 KSslCipher KTcpSocket::sessionCipher() const 0688 { 0689 return KSslCipher(d->sock.sessionCipher()); 0690 } 0691 0692 void KTcpSocket::setCaCertificates(const QList<QSslCertificate> &certificates) 0693 { 0694 QSslConfiguration configuration = d->sock.sslConfiguration(); 0695 configuration.setCaCertificates(certificates); 0696 d->sock.setSslConfiguration(configuration); 0697 d->certificatesLoaded = true; 0698 } 0699 0700 void KTcpSocket::setCiphers(const QList<KSslCipher> &ciphers) 0701 { 0702 d->ciphers = ciphers; 0703 QList<QSslCipher> cl; 0704 cl.reserve(d->ciphers.size()); 0705 for (const KSslCipher &c : ciphers) { 0706 cl.append(d->ccc.converted(c)); 0707 } 0708 QSslConfiguration configuration = d->sock.sslConfiguration(); 0709 configuration.setCiphers(cl); 0710 d->sock.setSslConfiguration(configuration); 0711 } 0712 0713 void KTcpSocket::setLocalCertificate(const QSslCertificate &certificate) 0714 { 0715 d->sock.setLocalCertificate(certificate); 0716 } 0717 0718 void KTcpSocket::setLocalCertificate(const QString &fileName, QSsl::EncodingFormat format) 0719 { 0720 d->sock.setLocalCertificate(fileName, format); 0721 } 0722 0723 void KTcpSocket::setVerificationPeerName(const QString &hostName) 0724 { 0725 d->sock.setPeerVerifyName(hostName); 0726 } 0727 0728 void KTcpSocket::setPrivateKey(const KSslKey &key) 0729 { 0730 // We cannot map KSslKey::Algorithm:Dh to anything in QSsl::KeyAlgorithm. 0731 if (key.algorithm() == KSslKey::Dh) { 0732 return; 0733 } 0734 0735 QSslKey _key(key.toDer(), 0736 (key.algorithm() == KSslKey::Rsa) ? QSsl::Rsa : QSsl::Dsa, 0737 QSsl::Der, 0738 (key.secrecy() == KSslKey::PrivateKey) ? QSsl::PrivateKey : QSsl::PublicKey); 0739 0740 d->sock.setPrivateKey(_key); 0741 } 0742 0743 void KTcpSocket::setPrivateKey(const QString &fileName, KSslKey::Algorithm algorithm, QSsl::EncodingFormat format, const QByteArray &passPhrase) 0744 { 0745 // We cannot map KSslKey::Algorithm:Dh to anything in QSsl::KeyAlgorithm. 0746 if (algorithm == KSslKey::Dh) { 0747 return; 0748 } 0749 0750 d->sock.setPrivateKey(fileName, (algorithm == KSslKey::Rsa) ? QSsl::Rsa : QSsl::Dsa, format, passPhrase); 0751 } 0752 0753 bool KTcpSocket::waitForEncrypted(int msecs) 0754 { 0755 return d->sock.waitForEncrypted(msecs); 0756 } 0757 0758 KTcpSocket::EncryptionMode KTcpSocket::encryptionMode() const 0759 { 0760 return d->encryptionMode(d->sock.mode()); 0761 } 0762 0763 QVariant KTcpSocket::socketOption(QAbstractSocket::SocketOption options) const 0764 { 0765 return d->sock.socketOption(options); 0766 } 0767 0768 void KTcpSocket::setSocketOption(QAbstractSocket::SocketOption options, const QVariant &value) 0769 { 0770 d->sock.setSocketOption(options, value); 0771 } 0772 0773 QSslConfiguration KTcpSocket::sslConfiguration() const 0774 { 0775 return d->sock.sslConfiguration(); 0776 } 0777 0778 void KTcpSocket::setSslConfiguration(const QSslConfiguration &configuration) 0779 { 0780 d->sock.setSslConfiguration(configuration); 0781 } 0782 0783 // slot 0784 void KTcpSocket::ignoreSslErrors() 0785 { 0786 d->sock.ignoreSslErrors(); 0787 } 0788 0789 // slot 0790 void KTcpSocket::startClientEncryption() 0791 { 0792 d->maybeLoadCertificates(); 0793 d->sock.setProtocol(qSslProtocolFromK(d->advertisedSslVersion)); 0794 d->sock.startClientEncryption(); 0795 } 0796 0797 // debugging H4X 0798 void KTcpSocket::showSslErrors() 0799 { 0800 const QList<QSslError> list = d->sock.sslHandshakeErrors(); 0801 for (const QSslError &e : list) { 0802 qCDebug(KIO_CORE) << e.errorString(); 0803 } 0804 } 0805 0806 void KTcpSocket::setAdvertisedSslVersion(KTcpSocket::SslVersion version) 0807 { 0808 d->advertisedSslVersion = version; 0809 } 0810 0811 KTcpSocket::SslVersion KTcpSocket::advertisedSslVersion() const 0812 { 0813 return d->advertisedSslVersion; 0814 } 0815 0816 KTcpSocket::SslVersion KTcpSocket::negotiatedSslVersion() const 0817 { 0818 if (!d->sock.isEncrypted()) { 0819 return UnknownSslVersion; 0820 } 0821 0822 return kSslVersionFromQ(d->sock.sessionProtocol()); 0823 } 0824 0825 QString KTcpSocket::negotiatedSslVersionName() const 0826 { 0827 if (!d->sock.isEncrypted()) { 0828 return QString(); 0829 } 0830 0831 return protocolString(d->sock.sessionProtocol()); 0832 } 0833 0834 ////////////////////////////// KSslKey 0835 0836 class KSslKeyPrivate 0837 { 0838 public: 0839 KSslKey::Algorithm convertAlgorithm(QSsl::KeyAlgorithm a) 0840 { 0841 switch (a) { 0842 case QSsl::Dsa: 0843 return KSslKey::Dsa; 0844 default: 0845 return KSslKey::Rsa; 0846 } 0847 } 0848 0849 KSslKey::Algorithm algorithm; 0850 KSslKey::KeySecrecy secrecy; 0851 bool isExportable; 0852 QByteArray der; 0853 }; 0854 0855 KSslKey::KSslKey() 0856 : d(new KSslKeyPrivate) 0857 { 0858 d->algorithm = Rsa; 0859 d->secrecy = PublicKey; 0860 d->isExportable = true; 0861 } 0862 0863 KSslKey::KSslKey(const KSslKey &other) 0864 : d(new KSslKeyPrivate) 0865 { 0866 *d = *other.d; 0867 } 0868 0869 KSslKey::KSslKey(const QSslKey &qsk) 0870 : d(new KSslKeyPrivate) 0871 { 0872 d->algorithm = d->convertAlgorithm(qsk.algorithm()); 0873 d->secrecy = (qsk.type() == QSsl::PrivateKey) ? PrivateKey : PublicKey; 0874 d->isExportable = true; 0875 d->der = qsk.toDer(); 0876 } 0877 0878 KSslKey::~KSslKey() = default; 0879 0880 KSslKey &KSslKey::operator=(const KSslKey &other) 0881 { 0882 *d = *other.d; 0883 return *this; 0884 } 0885 0886 KSslKey::Algorithm KSslKey::algorithm() const 0887 { 0888 return d->algorithm; 0889 } 0890 0891 bool KSslKey::isExportable() const 0892 { 0893 return d->isExportable; 0894 } 0895 0896 KSslKey::KeySecrecy KSslKey::secrecy() const 0897 { 0898 return d->secrecy; 0899 } 0900 0901 QByteArray KSslKey::toDer() const 0902 { 0903 return d->der; 0904 } 0905 0906 ////////////////////////////// KSslCipher 0907 0908 // nice-to-have: make implicitly shared 0909 class KSslCipherPrivate 0910 { 0911 public: 0912 QString authenticationMethod; 0913 QString encryptionMethod; 0914 QString keyExchangeMethod; 0915 QString name; 0916 bool isNull; 0917 int supportedBits; 0918 int usedBits; 0919 }; 0920 0921 KSslCipher::KSslCipher() 0922 : d(new KSslCipherPrivate) 0923 { 0924 d->isNull = true; 0925 d->supportedBits = 0; 0926 d->usedBits = 0; 0927 } 0928 0929 KSslCipher::KSslCipher(const KSslCipher &other) 0930 : d(new KSslCipherPrivate) 0931 { 0932 *d = *other.d; 0933 } 0934 0935 KSslCipher::KSslCipher(const QSslCipher &qsc) 0936 : d(new KSslCipherPrivate) 0937 { 0938 d->authenticationMethod = qsc.authenticationMethod(); 0939 d->encryptionMethod = qsc.encryptionMethod(); 0940 // Qt likes to append the number of bits (usedBits?) to the algorithm, 0941 // for example "AES(256)". We only want the pure algorithm name, though. 0942 int parenIdx = d->encryptionMethod.indexOf(QLatin1Char('(')); 0943 if (parenIdx > 0) { 0944 d->encryptionMethod.truncate(parenIdx); 0945 } 0946 d->keyExchangeMethod = qsc.keyExchangeMethod(); 0947 d->name = qsc.name(); 0948 d->isNull = qsc.isNull(); 0949 d->supportedBits = qsc.supportedBits(); 0950 d->usedBits = qsc.usedBits(); 0951 } 0952 0953 KSslCipher::~KSslCipher() = default; 0954 0955 KSslCipher &KSslCipher::operator=(const KSslCipher &other) 0956 { 0957 *d = *other.d; 0958 return *this; 0959 } 0960 0961 bool KSslCipher::isNull() const 0962 { 0963 return d->isNull; 0964 } 0965 0966 QString KSslCipher::authenticationMethod() const 0967 { 0968 return d->authenticationMethod; 0969 } 0970 0971 QString KSslCipher::encryptionMethod() const 0972 { 0973 return d->encryptionMethod; 0974 } 0975 0976 QString KSslCipher::keyExchangeMethod() const 0977 { 0978 return d->keyExchangeMethod; 0979 } 0980 0981 QString KSslCipher::digestMethod() const 0982 { 0983 // ### This is not really backend neutral. It works for OpenSSL and 0984 // for RFC compliant names, though. 0985 if (d->name.endsWith(QLatin1String("SHA"))) { 0986 return QStringLiteral("SHA-1"); 0987 } else if (d->name.endsWith(QLatin1String("MD5"))) { 0988 return QStringLiteral("MD5"); 0989 } else { 0990 return QString(); 0991 } 0992 } 0993 0994 QString KSslCipher::name() const 0995 { 0996 return d->name; 0997 } 0998 0999 int KSslCipher::supportedBits() const 1000 { 1001 return d->supportedBits; 1002 } 1003 1004 int KSslCipher::usedBits() const 1005 { 1006 return d->usedBits; 1007 } 1008 1009 // static 1010 QList<KSslCipher> KSslCipher::supportedCiphers() 1011 { 1012 QList<KSslCipher> ret; 1013 const QList<QSslCipher> candidates = QSslConfiguration::supportedCiphers(); 1014 ret.reserve(candidates.size()); 1015 for (const QSslCipher &c : candidates) { 1016 ret.append(KSslCipher(c)); 1017 } 1018 return ret; 1019 } 1020 1021 #include "moc_ktcpsocket.cpp" 1022 1023 #endif